diff --git a/.gitignore b/.gitignore index 848782f..f560c52 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,12 @@ target build bin .gradle + +# IntelliJ specific files/directories +out +.idea +*.ipr +*.iws +*.iml +atlassian-ide-plugin.xml + diff --git a/README.md b/README.md index 8d6e9b8..4dc78d3 100644 --- a/README.md +++ b/README.md @@ -13,13 +13,19 @@ My Java solutions for [LeetCode Online Judge](http://oj.leetcode.com/). ## Generate an eclipse project ```bash -gradle eclipse +./gradlew eclipse +``` + +## Generate an IntelliJ IDEA project + +```bash +./gradlew idea ``` ## Generate a file for a question ```bash -gradle question "-Pq=Some Question" +./gradlew question "-Pq=Some Question" ``` The above command will generate a source file called `src/main/java/some_question/SomeQuestion.java`, and you can write your solution in this file directly. @@ -31,6 +37,6 @@ Unit tests are also embedded as inner classes of the main code. For an explanati If you write some unit tests, you can use the following command to run them. ```bash -gradle test +./gradlew test ``` diff --git a/build.gradle b/build.gradle index 00f47a8..c7b56ad 100644 --- a/build.gradle +++ b/build.gradle @@ -1,8 +1,9 @@ apply plugin: 'java' apply plugin: 'eclipse' +apply plugin: 'idea' -sourceCompatibility = JavaVersion.VERSION_1_6 -targetCompatibility = JavaVersion.VERSION_1_6 +sourceCompatibility = JavaVersion.VERSION_1_8 +targetCompatibility = JavaVersion.VERSION_1_8 [compileJava, compileTestJava]*.options*.encoding = 'UTF-8' @@ -24,10 +25,15 @@ repositories { dependencies { compile 'junit:junit:4.10' + compile group: 'com.google.guava', name: 'guava', version: '23.5-jre' } sourceSets.test.java.srcDir 'src/main/java' +task wrapper(type: Wrapper) { + gradleVersion = '4.8.1' +} + task(question) << { def insertUnderlineIfStartsWithDigit = { s -> diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..0087cd3 Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..2336ccd --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Tue Dec 09 22:42:19 CST 2014 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-4.8.1-bin.zip diff --git a/gradlew b/gradlew new file mode 100755 index 0000000..91a7e26 --- /dev/null +++ b/gradlew @@ -0,0 +1,164 @@ +#!/usr/bin/env bash + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn ( ) { + echo "$*" +} + +die ( ) { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; +esac + +# For Cygwin, ensure paths are in UNIX format before anything is touched. +if $cygwin ; then + [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` +fi + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >&- +APP_HOME="`pwd -P`" +cd "$SAVED" >&- + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules +function splitJvmOpts() { + JVM_OPTS=("$@") +} +eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS +JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" + +exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000..aec9973 --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,90 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windowz variants + +if not "%OS%" == "Windows_NT" goto win9xME_args +if "%@eval[2+2]" == "4" goto 4NT_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* +goto execute + +:4NT_args +@rem Get arguments from the 4NT Shell from JP Software +set CMD_LINE_ARGS=%$ + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/src/main/java/.DS_Store b/src/main/java/.DS_Store new file mode 100644 index 0000000..174012e Binary files /dev/null and b/src/main/java/.DS_Store differ diff --git a/src/main/java/LCA_Binary_Search_Tree/LCABinarySearchTree.java b/src/main/java/LCA_Binary_Search_Tree/LCABinarySearchTree.java new file mode 100644 index 0000000..a2e80d6 --- /dev/null +++ b/src/main/java/LCA_Binary_Search_Tree/LCABinarySearchTree.java @@ -0,0 +1,24 @@ +package lca_binary_search_tree; + +import common.TreeNode; + +/** + * Created by lxie on 12/6/17. + */ +public class LCABinarySearchTree { + + public class Solution { + public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { + while (true) { + if (root.val > Integer.max(p.val, q.val)) root = root.left; + else if (root.val < Integer.min(p.val, q.val)) root = root.right; + else break; + } + return root; + } + } + + public static class UnitTest { + + } +} diff --git a/src/main/java/LCA_Binary_Tree/LCABinaryTree.java b/src/main/java/LCA_Binary_Tree/LCABinaryTree.java new file mode 100644 index 0000000..3bfa401 --- /dev/null +++ b/src/main/java/LCA_Binary_Tree/LCABinaryTree.java @@ -0,0 +1,26 @@ +package lca_binary_tree; + +import common.TreeNode; + +/** + * Created by lxie on 12/6/17. + */ +public class LCABinaryTree { + + public class Solution { + public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { + if (root == null || p == root || q == root) return root; + TreeNode left = lowestCommonAncestor(root.left, p, q); + TreeNode right = lowestCommonAncestor(root.right, p , q); + if (left != null && right != null) return root; + return left != null ? left : right; + } + + } + + public static class UnitTest { + + } + + +} diff --git a/src/main/java/LFU_cache/LFUCache.java b/src/main/java/LFU_cache/LFUCache.java new file mode 100644 index 0000000..62d8e69 --- /dev/null +++ b/src/main/java/LFU_cache/LFUCache.java @@ -0,0 +1,68 @@ +package LFU_cache; + +import common.Pair; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Created by lxie on 8/29/18. + */ +public class LFUCache { + + private int cap, minFreq; + private Map> m = new HashMap<>(); // key - value, freq + private Map> freq = new HashMap<>(); // freq - keys + private Map iter = new HashMap<>(); // key - key_pos in freq + + public LFUCache(int capacity) { + cap = capacity; + } + + public int get(int key) { + if (!m.containsKey(key)) return -1; + freq.get(m.get(key).getValue()).remove((int)iter.get(key)); + m.put(key, Pair.of(m.get(key).getKey(), m.get(key).getValue()+1)); + if (!freq.containsKey(m.get(key).getValue())) + freq.put(m.get(key).getValue(), new ArrayList<>()); + freq.get(m.get(key).getValue()).add(key); + iter.put(key, freq.get(m.get(key).getValue()).size()-1); + if (freq.get(minFreq).size() == 0) ++minFreq; + return m.get(key).getKey(); + } + + public void put(int key, int value) { + if (cap <= 0) return; + if (get(key) != -1) { + m.put(key, Pair.of(value, 1)); + return; + } + if (m.size() >= cap) { + m.remove(freq.get(minFreq).get(0)); + iter.remove(freq.get(minFreq).get(0)); + freq.get(minFreq).remove(0); + } + m.put(key, Pair.of(value, 1)); + if (!freq.containsKey(1)) freq.put(1, new ArrayList<>()); + freq.get(1).add(key); + iter.put(key, freq.get(1).size() - 1); + minFreq = 1; + } + + public static void main(String[] args) { + LFUCache cache = new LFUCache( 2 /* capacity */ ); + cache.put(1, 1); + cache.put(2, 2); + System.out.println(cache.get(1)); // returns 1 + cache.put(3, 3); // evicts key 2 + System.out.println(cache.get(2)); // returns -1 (not found) + System.out.println(cache.get(3)); // returns 3. + cache.put(4, 4); // evicts key 1. + System.out.println(cache.get(1)); // returns -1 (not found) + System.out.println(cache.get(3)); // returns 3 + System.out.println(cache.get(4)); // returns 4 + } + +} diff --git a/src/main/java/_24game/Solve24Game.java b/src/main/java/_24game/Solve24Game.java new file mode 100644 index 0000000..36bcd97 --- /dev/null +++ b/src/main/java/_24game/Solve24Game.java @@ -0,0 +1,55 @@ +package _24game; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by lxie on 8/27/18. + */ +public class Solve24Game { + + public class Solution { + + public boolean judgePoint24(int[] nums) { + double eps = 0.001; + char[] ops = {'+', '-', '*', '/'}; + double[] arr = new double[nums.length]; + for(int i=0; i t = new ArrayList<>(); + for (int k = 0; k < nums.length; ++k) { + if (k != i && k != j) t.add((double) nums[k]); + } + for (char op : ops) { + if ((op == '+' || op == '*') && i > j) continue; + if (op == '/' && nums[j] < eps) continue; + switch(op) { + case '+': t.add((double) nums[i] + nums[j]); break; + case '-': t.add((double) nums[i] - nums[j]); break; + case '*': t.add((double) nums[i] * nums[j]); break; + case '/': t.add((double) nums[i] / nums[j]); break; + } + double[] t1 = t.stream().mapToDouble(d -> d).toArray(); + if (helper(t1, ops, eps)) return true; + t.remove(t.size()-1); + } + } + } + return false; + } + } + + public class UnitTest { + + + } + +} diff --git a/src/main/java/_3sum/_3Sum.java b/src/main/java/_3sum/_3Sum.java index 328ff58..5c67d7a 100644 --- a/src/main/java/_3sum/_3Sum.java +++ b/src/main/java/_3sum/_3Sum.java @@ -1,56 +1,34 @@ package _3sum; -import java.util.ArrayList; -import java.util.Arrays; +import java.util.*; public class _3Sum { public class Solution { - private ArrayList makeTriplet(int a, int b, int c) { - ArrayList ans = new ArrayList(); - ans.add(a); - ans.add(b); - ans.add(c); - return ans; - } - - private void twoSum(ArrayList> ans, int a, - int[] num, int begin) { - int i = begin; - int j = num.length - 1; - while (i < j) { - int sum = num[i] + num[j]; - if (sum < -a) { - i++; - } else if (sum > -a) { - j--; - } else { - ans.add(makeTriplet(a, num[i], num[j])); - do { - i++; - } while (i < j && num[i] == num[i - 1]); - do { - j--; - } while (i < j && num[j] == num[j + 1]); - } - } - } - - public ArrayList> threeSum(int[] num) { - Arrays.sort(num); - ArrayList> ans = new ArrayList>(); - for (int i = 0; i < num.length - 2; i++) { - if (i > 0 && num[i] == num[i - 1]) { - continue; + public List> threeSum(int[] nums) { + Set> res = new HashSet<>(); + Arrays.sort(nums); + for (int k = 0; k < nums.length; ++k) { + if (nums[k] > 0) break; + int target = 0 - nums[k]; + int i = k + 1, j = nums.length - 1; + while (i < j) { + if (nums[i] + nums[j] == target) { + res.add(new ArrayList<>(Arrays.asList(nums[k], nums[i], nums[j]))); + while (i < j && nums[i] == nums[i + 1]) ++i; + while (i < j && nums[j] == nums[j - 1]) --j; + ++i; + --j; + } else if (nums[i] + nums[j] < target) ++i; + else --j; } - twoSum(ans, num[i], num, i + 1); } - return ans; + return new ArrayList<>(res); } } - public static class UnitTest { + public static class UnitTest { } } diff --git a/src/main/java/_3sum_closest/_3SumClosest.java b/src/main/java/_3sum_closest/_3SumClosest.java index 152eb89..9fce53c 100644 --- a/src/main/java/_3sum_closest/_3SumClosest.java +++ b/src/main/java/_3sum_closest/_3SumClosest.java @@ -1,35 +1,29 @@ package _3sum_closest; -import java.util.Arrays; +import java.util.*; public class _3SumClosest { public class Solution { - public int threeSumClosest(int[] num, int target) { - Arrays.sort(num); - int minSum = num[0] + num[1] + num[2]; - for (int i = 0; i < num.length - 2; i++) { - if (i > 0 && num[i] == num[i - 1]) { - continue; - } - int twoSum = target - num[i]; - int begin = i + 1; - int end = num.length - 1; - while (begin < end) { - int sum = num[begin] + num[end]; - if (Math.abs(twoSum - sum) < Math.abs(target - minSum)) { - minSum = sum + num[i]; - } - if (sum < twoSum) { - begin++; - } else if (sum > twoSum) { - end--; - } else { - return target; + public int threeSumClosest(int[] nums, int target) { + int closest = nums[0] + nums[1] + nums[2]; + int diff = Math.abs(closest - target); + Arrays.sort(nums); + for (int k = 0; k < nums.length; ++k) { + int i = k + 1, j = nums.length - 1; + while (i < j) { + int sum = nums[k] + nums[i] + nums[j]; + int newDiff = Math.abs(sum - target); + if (diff > newDiff) { + diff = newDiff; + closest = sum; } + if (sum < target) ++i; + else --j; + } } - return minSum; + return closest; } } diff --git a/src/main/java/_3sum_smaller/_3SumSmaller.java b/src/main/java/_3sum_smaller/_3SumSmaller.java new file mode 100644 index 0000000..9db21ec --- /dev/null +++ b/src/main/java/_3sum_smaller/_3SumSmaller.java @@ -0,0 +1,35 @@ +package _3sum_smaller; + +import java.util.Arrays; + +/** + * Created by lxie on 6/4/18. + */ +public class _3SumSmaller { + + public class Solution { + + public int threeSumSmaller(int[] nums, int target) { + if (nums.length < 3) return 0; + int res = 0; + Arrays.sort(nums); + for (int i = 0; i < nums.length - 2; ++i) { + int left = i + 1, right = nums.length - 1; + while (left < right) { + if (nums[i] + nums[left] + nums[right] < target) { + res += right - left; + ++left; + } else { + --right; + } + } + } + return res; + } + }; + + public class UnitTest { + + } + +} diff --git a/src/main/java/_4sum/_4Sum.java b/src/main/java/_4sum/_4Sum.java new file mode 100644 index 0000000..7af1619 --- /dev/null +++ b/src/main/java/_4sum/_4Sum.java @@ -0,0 +1,37 @@ +package _4sum; + +import java.util.*; + +public class _4Sum { + + public class Solution { + + public List> fourSum(int[] nums, int target) { + Set > res = new HashSet<>(); + Arrays.sort(nums); + for (int i = 0; i < (nums.length - 3); ++i) { + for (int j = i + 1; j < (nums.length - 2); ++j) { + int left = j + 1, right = nums.length - 1; + while (left < right) { + int sum = nums[i] + nums[j] + nums[left] + nums[right]; + if (sum == target) { + List out = new ArrayList<>(); + out.add(nums[i]); + out.add(nums[j]); + out.add(nums[left]); + out.add(nums[right]); + res.add(out); + ++left; --right; + } else if (sum < target) ++left; + else --right; + } + } + } + return new ArrayList<>(res); + } + } + + public static class UnitTest { + + } +} diff --git a/src/main/java/add_bold_tag_in_string/AddBoldTagInString.java b/src/main/java/add_bold_tag_in_string/AddBoldTagInString.java new file mode 100644 index 0000000..7644d69 --- /dev/null +++ b/src/main/java/add_bold_tag_in_string/AddBoldTagInString.java @@ -0,0 +1,42 @@ +package add_bold_tag_in_string; + +/** + * Created by lxie on 8/25/18. + */ +public class AddBoldTagInString { + + public String addBoldTag(String s, String[] dict) { + String res = ""; + int n = s.length(), end = 0; + boolean[] bold = new boolean[n]; + for (int i = 0; i < n; ++i) { + for (String word : dict) { + int len = word.length(); + if (i + len <= n && s.substring(i, i+len).equals(word)) { + end = Math.max(end, i + len); + } + } + bold[i] = end > i; + } + for (int i = 0; i < n; ++i) { + if (!bold[i]) { + res += (s.charAt(i)); + continue; + } + int j = i; + while (j < n && bold[j]) ++j; + res += "" + s.substring(i, j) + ""; + i = j-1; + } + return res; + } + + public static void main(String[] args) { + + AddBoldTagInString as = new AddBoldTagInString(); + String[] dict = {"abc","123"}; //{"aaa","aab","bc"}; + System.out.println(as.addBoldTag("abcxyz123", dict)); + + } + +} diff --git a/src/main/java/add_search_word/AddSearchWord.java b/src/main/java/add_search_word/AddSearchWord.java new file mode 100644 index 0000000..52c11b8 --- /dev/null +++ b/src/main/java/add_search_word/AddSearchWord.java @@ -0,0 +1,61 @@ +package add_search_word; + +/** + * Created by lxie on 2/7/18. + */ +public class AddSearchWord { + + public class WordDictionary { + + class TrieNode { + public TrieNode[] child = new TrieNode[26]; + public boolean isWord; + + public TrieNode() { + for (TrieNode a : child) a = null; + } + + } + + public TrieNode root; + + public WordDictionary(){ + root = new TrieNode(); + } + + public void addWord(String word) { + TrieNode p = root; + for (char a : word.toCharArray()) { + int i = a - 'a'; + if (p.child[i] == null) p.child[i] = new TrieNode(); + p = p.child[i]; + } + p.isWord = true; + } + + public boolean search(String word) { + return searchWord(word, root, 0); + } + + // use recursion for search to deal with wildcards + private boolean searchWord(String word, TrieNode p, int i) { + if (i == word.length()) return p.isWord; + if (word.toCharArray()[i] == '.') { + for (TrieNode a : p.child) { + if (a != null && searchWord(word, a, i + 1)) return true; + } + return false; + } else { + return p.child[word.toCharArray()[i] - 'a'] != null && + searchWord(word, p.child[word.toCharArray()[i] - 'a'], i + 1); + } + } + + } + + public static class UnitTest { + + + } + +} diff --git a/src/main/java/additive_number/AdditiveNumber.java b/src/main/java/additive_number/AdditiveNumber.java new file mode 100644 index 0000000..ba3f8c8 --- /dev/null +++ b/src/main/java/additive_number/AdditiveNumber.java @@ -0,0 +1,47 @@ +package additive_number; + +/** + * Created by lxie on 6/30/18. + */ +public class AdditiveNumber { + + public static class Solution { + + public boolean isAdditiveNumber(String num) { + for (int i = 1; i < num.length(); ++i) { + for (int j = i + 1; j < num.length(); ++j) { + String s1 = num.substring(0, i); + String s2 = num.substring(i, j); + long d1 = Long.parseLong(s1), d2 = Long.parseLong(s2); + if ((s1.length() > 1 && s1.charAt(0) == '0') || + (s2.length() > 1 && s2.charAt(0) == '0')) continue; + long next = d1 + d2; + String nexts = Long.toString(next); + String now = s1 + s2 + nexts; + while (now.length() < num.length()) { + d1 = d2; + d2 = next; + next = d1 + d2; + nexts = Long.toString(next); + now += nexts; + } + if (now.compareTo(num) == 0) return true; + } + } + return false; + } + + } + + public static void main(String[] args) { + + Solution sol = new Solution(); + boolean res = sol.isAdditiveNumber("112358"); + + System.out.println("result is " + res); + + + + } + +} diff --git a/src/main/java/alien_dictionary/AlienDictionary.java b/src/main/java/alien_dictionary/AlienDictionary.java new file mode 100644 index 0000000..0a8d8d1 --- /dev/null +++ b/src/main/java/alien_dictionary/AlienDictionary.java @@ -0,0 +1,86 @@ +package alien_dictionary; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.Queue; + +/** + * Created by lxie on 1/12/18. + */ +public class AlienDictionary { + + public class Solution { + public class Node { + public int degree; + public ArrayList neighbour = new ArrayList(); + void Node() { + degree = 0; + } + } + public String alienOrder(String[] words) { + Node[] node = new Node[26]; + boolean[] happen = new boolean[26]; // avoid duplicates, false by default + for (int i = 0; i < 26; i++) { + node[i] = new Node(); + } + //Build the Graph + for (int i = 0; i < words.length; i++) { + int startPoint = 0, endPoint = 0; + for (int j = 0; j < words[i].length(); j++) { + happen[charToInt(words[i].charAt(j))] = true; + } + if (i != words.length - 1) { + for (int j = 0; j < Math.min(words[i].length(), words[i + 1].length()); j++) { + if (words[i].charAt(j) != words[i + 1].charAt(j)) { + startPoint = charToInt(words[i].charAt(j)); + endPoint = charToInt(words[i + 1].charAt(j)); + break; + } + } + } + if (startPoint != endPoint) { + node[startPoint].neighbour.add(endPoint); + node[endPoint].degree++; + } + } + //Topological Sort + Queue queue = new LinkedList(); + String ans = ""; + for (int i = 0; i < 26; i++) { + if (node[i].degree == 0 && happen[i]) { + queue.offer(i); + ans = ans + intToChar(i); + } + } + while (!queue.isEmpty()) { + int now = queue.poll(); + for (int i : node[now].neighbour) { + node[i].degree--; + if (node[i].degree == 0) { + queue.offer(i); + ans = ans + intToChar(i); + } + } + } + for (int i = 0; i < 26; i++) { + if (node[i].degree != 0) { + return ""; + } + } + return ans; + } + public char intToChar(int i) { + return (char)('a' + i); + } + public int charToInt(char ch) { + return ch - 'a'; + } + + } + + public static class UnitTest { + + } + + +} diff --git a/src/main/java/all_O1_data_structure/AllO1DataStructure.java b/src/main/java/all_O1_data_structure/AllO1DataStructure.java new file mode 100644 index 0000000..a09043e --- /dev/null +++ b/src/main/java/all_O1_data_structure/AllO1DataStructure.java @@ -0,0 +1,76 @@ +package all_O1_data_structure; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.TreeMap; + +/** + * Created by lxie on 8/16/18. + */ +class AllOne { + /** + * 核心在于构建两个索引,一个是 key-fre,一个是fre-set(key) 这样才能实现快速的查找 + */ + TreeMap> reversedIndex; + HashMap index; + /** Initialize your data structure here. */ + public AllOne() { + this.reversedIndex = new TreeMap<>(); + this.index = new HashMap<>(); + } + + /** Inserts a new key with value 1. Or increments an existing key by 1. */ + + public void inc(String key) { + if (this.index.containsKey(key) == false){ + this.index.put(key,1); + if(this.reversedIndex.containsKey(1) == false) + this.reversedIndex.put(1,new HashSet()); + this.reversedIndex.get(1).add(key); + } else{ + int currentCounts = this.index.get(key); + this.reversedIndex.get(currentCounts).remove(key); + // 这里必须要做remove,因为treemap要直接firstkey()或者lastkey,下面dec同理 + if(this.reversedIndex.get(currentCounts).size() == 0){ + this.reversedIndex.remove(currentCounts); + } + if(this.reversedIndex.containsKey(currentCounts + 1) == false){ + this.reversedIndex.put(currentCounts + 1,new HashSet<>()); + } + this.index.put(key,currentCounts + 1); + this.reversedIndex.get(currentCounts + 1).add(key); + } + } + + /** Decrements an existing key by 1. If Key's value is 1, remove it from the data structure. */ + public void dec(String key) { + if(this.index.containsKey(key)){ + int currentCounts = this.index.get(key); + this.reversedIndex.get(currentCounts).remove(key); + if(this.reversedIndex.get(currentCounts).size() == 0){ + this.reversedIndex.remove(currentCounts); + } + if(currentCounts == 1){ + this.index.remove(key); + } else{ + if(this.reversedIndex.containsKey(currentCounts - 1) == false){ + this.reversedIndex.put(currentCounts - 1,new HashSet<>()); + } + this.reversedIndex.get(currentCounts -1).add(key); + this.index.put(key,currentCounts - 1); + } + } + } + + /** Returns one of the keys with maximal value. */ + public String getMaxKey() { + if (this.index.size() == 0 ) return ""; + return this.reversedIndex.get(this.reversedIndex.lastKey()).iterator().next(); + } + + /** Returns one of the keys with Minimal value. */ + public String getMinKey() { + if (this.index.size() == 0 ) return ""; + return this.reversedIndex.get(this.reversedIndex.firstKey()).iterator().next(); + } +} \ No newline at end of file diff --git a/src/main/java/anagrams/Anagrams.java b/src/main/java/anagrams/Anagrams.java new file mode 100644 index 0000000..f81e022 --- /dev/null +++ b/src/main/java/anagrams/Anagrams.java @@ -0,0 +1,37 @@ +package anagrams; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +public class Anagrams { + + public class Solution { + public List> groupAnagrams(String[] strs) { + Map> dict = new HashMap>(); + for (String str : strs) { + char[] cs = str.toCharArray(); + Arrays.sort(cs); + String anagram = new String(cs); + List l = dict.get(anagram); + if (l == null) { + l = new ArrayList(); + dict.put(anagram, l); + } + l.add(str); + } + List> ans = new ArrayList<>(); + for (Entry> e : dict.entrySet()) { + ans.add(e.getValue()); + } + return ans; + } + } + + public static class UnitTest { + + } +} diff --git a/src/main/java/android_unlock_patterns/AndroidUnlockPatterns.java b/src/main/java/android_unlock_patterns/AndroidUnlockPatterns.java new file mode 100644 index 0000000..96c6a9f --- /dev/null +++ b/src/main/java/android_unlock_patterns/AndroidUnlockPatterns.java @@ -0,0 +1,46 @@ +package android_unlock_patterns; + +/** + * Created by lxie on 10/24/17. + */ +public class AndroidUnlockPatterns { + public class Solution { + + public int numberOfPatterns(int m, int n) { + int res = 0; + Boolean[] visited = new Boolean[10]; + int[][] jumps = new int[10][10]; + jumps[1][3] = jumps[3][1] = 2; + jumps[4][6] = jumps[6][4] = 5; + jumps[7][9] = jumps[9][7] = 8; + jumps[1][7] = jumps[7][1] = 4; + jumps[2][8] = jumps[8][2] = 5; + jumps[3][9] = jumps[9][3] = 6; + jumps[1][9] = jumps[9][1] = jumps[3][7] = jumps[7][3] = 5; + res += helper(1, 1, 0, m, n, jumps, visited) * 4; + res += helper(2, 1, 0, m, n, jumps, visited) * 4; + res += helper(5, 1, 0, m, n, jumps, visited); + return res; + } + + private int helper(int num, int len, int res, int m, int n, int[][] jumps, Boolean[] visited) { + if (len >= m) ++res; + ++len; + if (len > n) return res; + visited[num] = true; + for (int next = 1; next <= 9; ++next) { + int jump = jumps[num][next]; + if (!visited[next] && (jump == 0 || visited[jump])) { + res = helper(next, len, res, m, n, jumps, visited); + } + } + visited[num] = false; + return res; + } + } + + public static class UnitTest { + + } + +} diff --git a/src/main/java/average_of_levels_btree/AvgLevelsBTree.java b/src/main/java/average_of_levels_btree/AvgLevelsBTree.java new file mode 100644 index 0000000..1af0375 --- /dev/null +++ b/src/main/java/average_of_levels_btree/AvgLevelsBTree.java @@ -0,0 +1,42 @@ +package average_of_levels_btree; + +import common.TreeNode; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; +import java.util.Queue; + +/** + * Created by lxie on 10/8/18. + */ +public class AvgLevelsBTree { + + public class Solution { + + List averageOfLevels(TreeNode root) { + List res = new ArrayList<>(); + if (root == null) return res; + Queue q = new LinkedList<>(); q.add(root); + while (!q.isEmpty()) { + int n = q.size(); + double sum = 0; + for (int i = 0; i < n; ++i) { + TreeNode t = q.peek(); q.poll(); + sum += t.val; + if (t.left != null) q.add(t.left); + if (t.right != null) q.add(t.right); + } + res.add(sum / n); + } + return res; + } + + } + + public class UnitTest { + + + } + +} diff --git a/src/main/java/basic_calculator/BasicCalculator.java b/src/main/java/basic_calculator/BasicCalculator.java new file mode 100644 index 0000000..69a9785 --- /dev/null +++ b/src/main/java/basic_calculator/BasicCalculator.java @@ -0,0 +1,38 @@ +package basic_calculator; + +import java.util.Stack; + +/** + * Created by lxie on 2/14/18. + */ +public class BasicCalculator { + + public class Solution { + + int calculate(String s) { + int res = 0; + Stack sign = new Stack<>(); + sign.push(1); sign.push(1); + char[] str = s.toCharArray(); + for (int i = 0; i < s.length(); ++i) { + char c = str[i]; + if (c >= '0') { + int num = 0; + while (i < s.length() && str[i] >= '0') { + num = 10 * num + str[i++] - '0'; + } + res += sign.peek() * num; + sign.pop(); + --i; + } + else if (c == ')') sign.pop(); + else if (c != ' ') sign.push(sign.peek() * (c == '-' ? -1 : 1)); + } + return res; + } + } + + public static class UnitTest { + + } +} diff --git a/src/main/java/basic_calculator_ii/BasicCalculatorII.java b/src/main/java/basic_calculator_ii/BasicCalculatorII.java new file mode 100644 index 0000000..e01603f --- /dev/null +++ b/src/main/java/basic_calculator_ii/BasicCalculatorII.java @@ -0,0 +1,45 @@ +package basic_calculator_ii; + +import java.util.Stack; + +/** + * Created by lxie on 2/21/18. + */ +public class BasicCalculatorII { + + public class Solution { + public int calculate(String s) { + int res = 0, d = 0; + char sign = '+'; + char[] str = s.toCharArray(); + Stack nums = new Stack<>(); + for (int i = 0; i < s.length(); ++i) { + if (str[i] >= '0') { + d = d * 10 + str[i] - '0'; + } + if ((str[i] < '0' && str[i] != ' ') || i == s.length() - 1) { + if (sign == '+') nums.push(d); + if (sign == '-') nums.push(-d); + if (sign == '*' || sign == '/') { + int tmp = sign == '*' ? nums.peek() * d : nums.peek() / d; + nums.pop(); + nums.push(tmp); + } + sign = str[i]; // operator before number + d = 0; + } + } + while (!nums.empty()) { + res += nums.peek(); + nums.pop(); + } + return res; + + } + } + + public static class UnitTest { + + } + +} diff --git a/src/main/java/battleships_in_board/BattleShipsInBoard.java b/src/main/java/battleships_in_board/BattleShipsInBoard.java new file mode 100644 index 0000000..adf2dcb --- /dev/null +++ b/src/main/java/battleships_in_board/BattleShipsInBoard.java @@ -0,0 +1,45 @@ +package battleships_in_board; + +/** + * Created by lxie on 9/16/17. + */ +public class BattleShipsInBoard { + + class Solution { + public int countBattleships(char[][] board) { + if (board.length == 0 || board[0].length == 0) return 0; + int m = board.length, n = board[0].length, res = 0; + boolean[][] visited = new boolean[m][n]; // default is all false + + for (int i = 0; i < m; ++i) { + for (int j = 0; j < n; ++j) { + if (board[i][j] == 'X' && !visited[i][j]) { + int[] lineAndCol = {0, 0}; + dfs(board, visited, lineAndCol, i, j); + if (lineAndCol[0] == i || lineAndCol[1] == j) ++res; + } + } + } + return res; + } + void dfs(char[][] board, boolean[][] visited, int[] linecol, int i, int j) { + int m = board.length, n = board[0].length; + if (i < 0 || i >= m || j < 0 || j >= n || visited[i][j] || board[i][j] == '.') return; + linecol[0] |= i; linecol[1] |= j; + visited[i][j] = true; + dfs(board, visited, linecol, i - 1, j); + dfs(board, visited, linecol, i + 1, j); + dfs(board, visited, linecol, i, j - 1); + dfs(board, visited, linecol, i, j + 1); + } + + } + + + public static void main(String[] args) { + System.out.println("this is for test"); + } + + + +} diff --git a/src/main/java/beautiful_arrangement/BeautifulArrangement.java b/src/main/java/beautiful_arrangement/BeautifulArrangement.java new file mode 100644 index 0000000..fff8537 --- /dev/null +++ b/src/main/java/beautiful_arrangement/BeautifulArrangement.java @@ -0,0 +1,36 @@ +package beautiful_arrangement; + +/** + * Created by lxie on 7/24/18. + */ +public class BeautifulArrangement { + + public class Solution { + + public int countArrangement(int N) { + int[] res = {0}; + int[] visited = new int[N + 1]; + helper(N, visited, 1, res); + return res[0]; + } + void helper(int N, int[] visited, int pos, int[] res) { + if (pos > N) { + ++res[0]; + return; + } + for (int i = 1; i <= N; ++i) { + if (visited[i] == 0 && (i % pos == 0 || pos % i == 0)) { + visited[i] = 1; + helper(N, visited, pos + 1, res); + visited[i] = 0; + } + } + } + } + + public class UnitTest { + + } + + +} diff --git a/src/main/java/beautiful_arrangement_ii/BeautifulArrangementII.java b/src/main/java/beautiful_arrangement_ii/BeautifulArrangementII.java new file mode 100644 index 0000000..4656643 --- /dev/null +++ b/src/main/java/beautiful_arrangement_ii/BeautifulArrangementII.java @@ -0,0 +1,27 @@ +package beautiful_arrangement_ii; + +/** + * Created by lxie on 9/17/18. + */ +public class BeautifulArrangementII { + + public class Solution { + + public int[] constructArray(int n, int k) { + int[] res = new int[n]; + int i = 1, j = n, t = 0; + while (i <= j) { + if (k > 1) res[t++] = (k-- % 2 != 0? i++ : j--); + else res[t++] = (i++); + } + return res; + } + + + } + + public class UnitTest { + + + } +} diff --git a/src/main/java/best_meeting_point/BestMeetingPoint.java b/src/main/java/best_meeting_point/BestMeetingPoint.java new file mode 100644 index 0000000..92ad29a --- /dev/null +++ b/src/main/java/best_meeting_point/BestMeetingPoint.java @@ -0,0 +1,41 @@ +package best_meeting_point; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * Created by lxie on 6/20/18. + */ +public class BestMeetingPoint { + + public class Solution { + + public int minTotalDistance(int[][] grid) { + List rows = new ArrayList(); + List cols = new ArrayList(); + for (int i = 0; i < grid.length; ++i) { + for (int j = 0; j < grid[i].length; ++j) { + if (grid[i][j] == 1) { + rows.add(i); + cols.add(j); + } + } + } + return minTotalDistance(rows) + minTotalDistance(cols); + } + int minTotalDistance(List v) { + int res = 0; + Collections.sort(v); + int i = 0, j = v.size() - 1; + while (i < j) res += v.get(j--) - v.get(i++); + return res; + } + + } + + public class UnitTest { + + } + +} diff --git a/src/main/java/best_time_to_buy_and_sell_stock/BestTimetoBuyandSellStock.java b/src/main/java/best_time_to_buy_and_sell_stock/BestTimetoBuyandSellStock.java index 9ea71b8..2a320aa 100644 --- a/src/main/java/best_time_to_buy_and_sell_stock/BestTimetoBuyandSellStock.java +++ b/src/main/java/best_time_to_buy_and_sell_stock/BestTimetoBuyandSellStock.java @@ -4,16 +4,12 @@ public class BestTimetoBuyandSellStock { public class Solution { public int maxProfit(int[] prices) { - if (prices.length == 0) { - return 0; + int res = 0, buy = Integer.MAX_VALUE; + for (int price : prices) { + buy = Math.min(buy, price); + res = Math.max(res, price - buy); } - int maxProfit = 0; - int minPrice = prices[0]; - for (int i = 1; i < prices.length; i++) { - maxProfit = Math.max(maxProfit, prices[i] - minPrice); - minPrice = Math.min(minPrice, prices[i]); - } - return maxProfit; + return res; } } diff --git a/src/main/java/best_time_to_buy_and_sell_stock_cool_down/BestTimetoBuyandSellStockCoolDown.java b/src/main/java/best_time_to_buy_and_sell_stock_cool_down/BestTimetoBuyandSellStockCoolDown.java new file mode 100644 index 0000000..4dd1eb8 --- /dev/null +++ b/src/main/java/best_time_to_buy_and_sell_stock_cool_down/BestTimetoBuyandSellStockCoolDown.java @@ -0,0 +1,18 @@ +package best_time_to_buy_and_sell_stock_cool_down; + +public class BestTimetoBuyandSellStockCoolDown { + + public class Solution { + public int maxProfit(int[] prices) { + int buy = Integer.MIN_VALUE, pre_buy = 0, sell = 0, pre_sell = 0; + for (int price : prices) { + pre_buy = buy; + buy = Integer.max(pre_sell - price, pre_buy); + pre_sell = sell; + sell = Integer.max(pre_buy + price, pre_sell); + } + return sell; + } + } +} + diff --git a/src/main/java/best_time_to_buy_and_sell_stock_iii/BestTimetoBuyandSellStockIII.java b/src/main/java/best_time_to_buy_and_sell_stock_iii/BestTimetoBuyandSellStockIII.java index 6c3a9fe..7632e55 100644 --- a/src/main/java/best_time_to_buy_and_sell_stock_iii/BestTimetoBuyandSellStockIII.java +++ b/src/main/java/best_time_to_buy_and_sell_stock_iii/BestTimetoBuyandSellStockIII.java @@ -4,24 +4,38 @@ public class BestTimetoBuyandSellStockIII { public class Solution { public int maxProfit(int[] prices) { - if (prices.length == 0) { - return 0; - } - int[] profit = new int[prices.length]; - profit[0] = 0; - int minPrice = prices[0]; - for (int i = 1; i < prices.length; i++) { - profit[i] = Math.max(profit[i - 1], prices[i] - minPrice); - minPrice = Math.min(minPrice, prices[i]); + int len = prices.length; + if (len==0) return 0; + + int[] historyProfit = new int[len]; + int[] futureProfit = new int[len]; + + int valley = prices[0]; + int peak = prices[len-1]; + int maxProfit = 0; + + // forward, calculate max profit until this time + for (int i = 0; i0) + { + historyProfit[i] = Integer.max(historyProfit[i-1],prices[i]-valley); + } } - int maxPrice = prices[prices.length - 1]; - int maxProfit = profit[prices.length - 1]; - for (int i = prices.length - 2; i > 0; i--) { - maxProfit = Math.max(maxProfit, profit[i - 1] + maxPrice - - prices[i]); - maxPrice = Math.max(maxPrice, prices[i]); + + // backward, calculate max profit from now, and then sum with history + for (int i = len-1; i>=0; --i) + { + peak = Integer.max(peak, prices[i]); + if (i= n) { + return maxProfitUnlimited(prices); + } + int[] global = new int[k + 1]; + int[] local = new int[k + 1]; + for (int i = 1; i < n; i++) { + int diff = prices[i] - prices[i - 1]; + for (int j = k; j >= 1; j--) { + local[j] = Math.max(global[j - 1] + Math.max(diff, 0), local[j] + diff); + global[j] = Math.max(global[j], local[j]); + } + } + return global[k]; + } + } +} + diff --git a/src/main/java/binary_search_tree_iterator/BinarySearchTreeIterator.java b/src/main/java/binary_search_tree_iterator/BinarySearchTreeIterator.java new file mode 100644 index 0000000..97fee95 --- /dev/null +++ b/src/main/java/binary_search_tree_iterator/BinarySearchTreeIterator.java @@ -0,0 +1,60 @@ +package binary_search_tree_iterator; + +import java.util.ArrayDeque; + +import common.TreeNode; + +public class BinarySearchTreeIterator { + + public class BSTIterator { + + private ArrayDeque stack = new ArrayDeque(); + + private TreeNode current = null; + + public BSTIterator(TreeNode root) { + pushNode(root); + } + + private void pushNode(TreeNode node) { + while (node != null) { + stack.push(node); + node = node.left; + } + } + + /** + * @return whether we have a next smallest number + */ + public boolean hasNext() { + if (current == null) { + if (stack.isEmpty()) { + return false; + } else { + current = stack.pop(); + pushNode(current.right); + } + } + return true; + } + + /** + * @return the next smallest number + */ + public int next() { + if (hasNext()) { + int val = current.val; + current = null; + return val; + } else { + // Follow the contract of java.util.Iterator + throw new java.util.NoSuchElementException(); + } + } + } + + public static class UnitTest { + + } +} + diff --git a/src/main/java/binary_tree_inorder_traversal/BinaryTreeInorderTraversal.java b/src/main/java/binary_tree_inorder_traversal/BinaryTreeInorderTraversal.java index 50e50ed..5c7cd24 100644 --- a/src/main/java/binary_tree_inorder_traversal/BinaryTreeInorderTraversal.java +++ b/src/main/java/binary_tree_inorder_traversal/BinaryTreeInorderTraversal.java @@ -1,35 +1,29 @@ package binary_tree_inorder_traversal; -import java.util.ArrayList; - import common.TreeNode; +import java.util.ArrayList; +import java.util.Stack; + public class BinaryTreeInorderTraversal { public class Solution { public ArrayList inorderTraversal(TreeNode root) { ArrayList ans = new ArrayList(); + Stack s = new Stack<>(); TreeNode p = root; - while (p != null) { - if (p.left == null) { - ans.add(p.val); - p = p.right; - } else { - TreeNode temp = p.left; - while (temp.right != null && temp.right != p) { - temp = temp.right; - } - if (temp.right == null) { - temp.right = p; - p = p.left; - } else { - ans.add(p.val); - temp.right = null; - p = p.right; - } + while (p != null || !s.empty()) { + while (p != null) { + s.push(p); + p = p.left; } + p = s.peek(); + s.pop(); + ans.add(p.val); + p = p.right; } return ans; + } } diff --git a/src/main/java/binary_tree_longest_consecutive_sequence/LongestConsecutiveSequenceBTree.java b/src/main/java/binary_tree_longest_consecutive_sequence/LongestConsecutiveSequenceBTree.java new file mode 100644 index 0000000..00a2d2d --- /dev/null +++ b/src/main/java/binary_tree_longest_consecutive_sequence/LongestConsecutiveSequenceBTree.java @@ -0,0 +1,44 @@ +package binary_tree_longest_consecutive_sequence; + +import common.TreeNode; + +import static java.lang.Math.max; + +/** + * Created by lxie on 6/21/18. + */ +public class LongestConsecutiveSequenceBTree { + + public static class Solution { + + public int longestConsecutive(TreeNode root) { + if (root == null) return 0; + int[] res = {0}; + dfs(root, root.val - 1, 0, res); + return res[0]; + } + + private void dfs(TreeNode root, int v, int out, int[] res) { + if (root == null) return; + if (root.val == v + 1) ++out; + else out = 1; + res[0] = max(res[0], out); + dfs(root.left, root.val, out, res); + dfs(root.right, root.val, out, res); + } + } + + public static void main(String[] args) { + Solution sol = new Solution(); + + TreeNode root = new TreeNode(1); + root.right = new TreeNode(3); + root.right.left = new TreeNode(2); + root.right.right = new TreeNode(4); + root.right.right.right = new TreeNode(5); + int res = sol.longestConsecutive(root); + System.out.println("result is " + res); + } + + +} diff --git a/src/main/java/binary_tree_longest_consecutive_sequence_ii/BinaryTreeLongestConsecutiveSequenceII.java b/src/main/java/binary_tree_longest_consecutive_sequence_ii/BinaryTreeLongestConsecutiveSequenceII.java new file mode 100644 index 0000000..0b1d6d6 --- /dev/null +++ b/src/main/java/binary_tree_longest_consecutive_sequence_ii/BinaryTreeLongestConsecutiveSequenceII.java @@ -0,0 +1,38 @@ +package binary_tree_longest_consecutive_sequence_ii; + +import common.TreeNode; + +/** + * Created by lxie on 9/15/18. + */ +public class BinaryTreeLongestConsecutiveSequenceII { + + public class Solution { + + public int longestConsecutive(TreeNode root) { + if (root == null) return 0; + int res = helper(root, 1) + helper(root, -1) + 1; + return Math.max(res, Math.max(longestConsecutive(root.left), longestConsecutive(root.right))); + } + + private int helper(TreeNode node, int diff) { + if (node == null) return 0; + int left = 0, right = 0; + if (node.left != null && node.val - node.left.val == diff) { + left = 1 + helper(node.left, diff); + } + if (node.right != null && node.val - node.right.val == diff) { + right = 1 + helper(node.right, diff); + } + return Math.max(left, right); + } + + } + + public class UnitTest { + + + + } + +} diff --git a/src/main/java/binary_tree_maximum_path_sum/BinaryTreeMaximumPathSum.java b/src/main/java/binary_tree_maximum_path_sum/BinaryTreeMaximumPathSum.java index fdd0fc9..a63cb96 100644 --- a/src/main/java/binary_tree_maximum_path_sum/BinaryTreeMaximumPathSum.java +++ b/src/main/java/binary_tree_maximum_path_sum/BinaryTreeMaximumPathSum.java @@ -5,36 +5,21 @@ public class BinaryTreeMaximumPathSum { public class Solution { - private int maxPathSum(TreeNode root, int[] partSum) { - int leftSum = 0; - int leftPartSum = 0; - int rightSum = 0; - int rightPartSum = 0; - if (root.left != null) { - leftSum = maxPathSum(root.left, partSum); - leftPartSum = partSum[0] > 0 ? partSum[0] : 0; - } - if (root.right != null) { - rightSum = maxPathSum(root.right, partSum); - rightPartSum = partSum[0] > 0 ? partSum[0] : 0; - } - int maxSum = leftPartSum + rightPartSum + root.val; - if (root.left != null) { - maxSum = Math.max(maxSum, leftSum); - } - if (root.right != null) { - maxSum = Math.max(maxSum, rightSum); - } - partSum[0] = Math.max(leftPartSum, rightPartSum) + root.val; - return maxSum; - } public int maxPathSum(TreeNode root) { - if (root == null) { - return 0; - } - return maxPathSum(root, new int[1]); + int[] res = {Integer.MIN_VALUE}; + helper(root, res); + return res[0]; + } + + private int helper(TreeNode node, int[] res) { + if (node == null) return 0; + int left = Math.max(helper(node.left, res), 0); + int right = Math.max(helper(node.right, res), 0); + res[0] = Math.max(res[0], left + right + node.val); + return Math.max(left, right) + node.val; } + } public static class UnitTest { diff --git a/src/main/java/binary_tree_paths/BinaryTreePaths.java b/src/main/java/binary_tree_paths/BinaryTreePaths.java new file mode 100644 index 0000000..279dae8 --- /dev/null +++ b/src/main/java/binary_tree_paths/BinaryTreePaths.java @@ -0,0 +1,41 @@ +package binary_tree_paths; + +import common.TreeNode; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by lxie on 6/3/18. + */ +public class BinaryTreePaths { + + public static class Solution { + + public List binaryTreePaths(TreeNode root) { + List res = new ArrayList<>(); + if (root != null) dfs(root, "", res); + return res; + } + + public void dfs(TreeNode root, String out, List res) { + out += Integer.toString(root.val); + if (root.left == null && root.right == null) res.add(out); + else { + if (root.left != null) dfs(root.left, out + "->", res); + if (root.right != null) dfs(root.right, out + "->", res); + } // out is not string & + } + } + + public static void main(String[] args) { + Solution sol = new Solution(); + + TreeNode root = new TreeNode(1); + root.left = new TreeNode(2); root.right = new TreeNode(3); + root.left.right = new TreeNode(5); + List res = sol.binaryTreePaths(root); + System.out.println("result is " + res); + } + +} diff --git a/src/main/java/binary_tree_postorder_traversal/BinaryTreePostorderTraversal.java b/src/main/java/binary_tree_postorder_traversal/BinaryTreePostorderTraversal.java new file mode 100644 index 0000000..7e52452 --- /dev/null +++ b/src/main/java/binary_tree_postorder_traversal/BinaryTreePostorderTraversal.java @@ -0,0 +1,37 @@ +package binary_tree_postorder_traversal; + +import common.TreeNode; + +import java.util.ArrayList; +import java.util.List; +import java.util.Stack; + +public class BinaryTreePostorderTraversal { + + public class Solution { + public List postorderTraversal(TreeNode root) { + List res = new ArrayList<>(); + if (root == null) return res; + Stack s = new Stack<>(); + s.push(root); + TreeNode head = root; + while (!s.empty()) { + TreeNode t = s.peek(); + if ((t.left == null && t.right == null) || + t.left == head || t.right == head) { + res.add(t.val); + s.pop(); + head = t; // set head to t after added to res + } else { + if (t.right != null) s.push(t.right); + if (t.left != null) s.push(t.left); + } + } + return res; + } + } + + public static class UnitTest { + + } +} diff --git a/src/main/java/binary_tree_preorder_traversal/BinaryTreePreorderTraversal.java b/src/main/java/binary_tree_preorder_traversal/BinaryTreePreorderTraversal.java new file mode 100644 index 0000000..4214ac1 --- /dev/null +++ b/src/main/java/binary_tree_preorder_traversal/BinaryTreePreorderTraversal.java @@ -0,0 +1,30 @@ +package binary_tree_preorder_traversal; + +import common.TreeNode; + +import java.util.ArrayList; +import java.util.List; +import java.util.Stack; + +public class BinaryTreePreorderTraversal { + + public class Solution { + public List preorderTraversal(TreeNode root) { + List res = new ArrayList<>(); + if (root == null) return res; + Stack s = new Stack<>(); + s.push(root); + while (!s.empty()) { + TreeNode t = s.peek(); s.pop(); + res.add(t.val); + if (t.right != null) s.push(t.right); + if (t.left != null) s.push(t.left); + } + return res; + } + } + + public static class UnitTest { + + } +} diff --git a/src/main/java/binary_tree_right_side_view/BinaryTreeRightSideView.java b/src/main/java/binary_tree_right_side_view/BinaryTreeRightSideView.java new file mode 100644 index 0000000..d01c8b2 --- /dev/null +++ b/src/main/java/binary_tree_right_side_view/BinaryTreeRightSideView.java @@ -0,0 +1,34 @@ +package binary_tree_right_side_view; + +import common.TreeNode; + +import java.util.ArrayList; +import java.util.List; + +public class BinaryTreeRightSideView { + + public class Solution { + public List rightSideView(TreeNode root) { + List result = new ArrayList(); + if (root != null) { + List level = new ArrayList(); + level.add(root); + while (!level.isEmpty()) { + result.add(level.get(level.size() - 1).val); + List nextLevel = new ArrayList(); + for (TreeNode node : level) { + if (node.left != null) { + nextLevel.add(node.left); + } + if (node.right != null) { + nextLevel.add(node.right); + } + } + level = nextLevel; + } + } + return result; + } + } +} + diff --git a/src/main/java/binary_tree_upside_down/UpsideDownBinaryTree.java b/src/main/java/binary_tree_upside_down/UpsideDownBinaryTree.java new file mode 100644 index 0000000..46675c3 --- /dev/null +++ b/src/main/java/binary_tree_upside_down/UpsideDownBinaryTree.java @@ -0,0 +1,43 @@ +package binary_tree_upside_down; + +import common.TreeNode; + +/** + * Created by lxie on 2/1/18. + */ +public class UpsideDownBinaryTree { + + public class Solution { + TreeNode upsideDownBinaryTree(TreeNode root) { + if (root == null || root.left == null) return root; + TreeNode l = root.left, r = root.right; + TreeNode res = upsideDownBinaryTree(l); + l.left = r; + l.right = root; + root.left = null; + root.right = null; + return res; + } + + TreeNode upsideDownBinaryTree1(TreeNode root) { + TreeNode cur = root, pre = null, next = null, tmp = null; + while (cur != null) { + next = cur.left; + cur.left = tmp; + tmp = cur.right; + cur.right = pre; + pre = cur; + cur = next; + } + return pre; + } + + } + + public static class UnitTest { + + + } + + +} diff --git a/src/main/java/binary_tree_vertical_traversal/BinaryTreeVerticalTraversal.java b/src/main/java/binary_tree_vertical_traversal/BinaryTreeVerticalTraversal.java new file mode 100644 index 0000000..2503e88 --- /dev/null +++ b/src/main/java/binary_tree_vertical_traversal/BinaryTreeVerticalTraversal.java @@ -0,0 +1,56 @@ +package binary_tree_vertical_traversal; + +import common.TreeNode; + +import java.util.*; + +/** + * Created by lxie on 1/29/18. + */ +public class BinaryTreeVerticalTraversal { + + public class Solution { + + public List> verticalOrder(TreeNode root) { + List> results = new ArrayList<>(); + if (root == null) { + return results; + } + Map> map = new TreeMap>(); + Queue qCol = new LinkedList<>(); + Queue queue = new LinkedList<>(); + queue.offer(root); + qCol.offer(0); + + while(!queue.isEmpty()) { + TreeNode curr = queue.poll(); + int col = qCol.poll(); + if(!map.containsKey(col)) { + map.put(col, new ArrayList(Arrays.asList(curr.val))); + } else { + map.get(col).add(curr.val); + } + if(curr.left != null) { + queue.offer(curr.left); + qCol.offer(col - 1); + } + if(curr.right != null) { + queue.offer(curr.right); + qCol.offer(col + 1); + } + } + for(int n : map.keySet()) { + results.add(map.get(n)); + } + return results; + } + + } + + public static class UnitTest { + + + } + + +} diff --git a/src/main/java/binary_tree_zigzag_level_order_traversal/BinaryTreeZigzagLevelOrderTraversal.java b/src/main/java/binary_tree_zigzag_level_order_traversal/BinaryTreeZigzagLevelOrderTraversal.java new file mode 100644 index 0000000..9f44de8 --- /dev/null +++ b/src/main/java/binary_tree_zigzag_level_order_traversal/BinaryTreeZigzagLevelOrderTraversal.java @@ -0,0 +1,51 @@ +package binary_tree_zigzag_level_order_traversal; + +import java.util.ArrayList; + +import common.TreeNode; + +public class BinaryTreeZigzagLevelOrderTraversal { + + public class Solution { + public ArrayList> zigzagLevelOrder(TreeNode root) { + ArrayList> ans = new ArrayList>(); + if (root == null) { + return ans; + } + ArrayList q = new ArrayList(); + q.add(root); + int tail = 0; + boolean reverse = false; + while (tail != q.size()) { + int begin = tail; + tail = q.size(); + for (int i = begin; i < tail; i++) { + TreeNode p = q.get(i); + if (p.left != null) { + q.add(p.left); + } + if (p.right != null) { + q.add(p.right); + } + } + ArrayList level = new ArrayList(); + if (reverse) { + for (int i = tail - 1; i >= begin; i--) { + level.add(q.get(i).val); + } + } else { + for (int i = begin; i < tail; i++) { + level.add(q.get(i).val); + } + } + ans.add(level); + reverse = !reverse; + } + return ans; + } + } + + public static class UnitTest { + + } +} diff --git a/src/main/java/binary_watch/BinaryWatch.java b/src/main/java/binary_watch/BinaryWatch.java new file mode 100644 index 0000000..475275c --- /dev/null +++ b/src/main/java/binary_watch/BinaryWatch.java @@ -0,0 +1,52 @@ +package binary_watch; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by lxie on 7/14/18. + */ +public class BinaryWatch { + + public class Solution { + + public List readBinaryWatch(int num) { + List res = new ArrayList<>(); + int[] hour = {8, 4, 2, 1}; int[] minute = {32, 16, 8, 4, 2, 1}; + for (int i = 0; i <= num; ++i) { + List hours = generate(hour, i); + List minutes = generate(minute, num - i); + for (int h : hours) { + if (h > 11) continue; + for (int m : minutes) { + if (m > 59) continue; + res.add(Integer.toString(h) + (m < 10 ? ":0" : ":") + Integer.toString(m)); + } + } + } + return res; + } + + private List generate(int[] nums, int cnt) { + List res = new ArrayList<>(); + helper(nums, cnt, 0, 0, res); + return res; + } + + private void helper(int[] nums, int cnt, int pos, int out, List res) { + if (cnt == 0) { + res.add(out); + return; + } + for (int i = pos; i < nums.length; ++i) { + helper(nums, cnt - 1, i + 1, out + nums[i], res); + } + } + + } + + public class UnitTest { + + + } +} diff --git a/src/main/java/bitwise_and_of_numbers_range/BitwiseANDofNumbersRange.java b/src/main/java/bitwise_and_of_numbers_range/BitwiseANDofNumbersRange.java new file mode 100644 index 0000000..b453547 --- /dev/null +++ b/src/main/java/bitwise_and_of_numbers_range/BitwiseANDofNumbersRange.java @@ -0,0 +1,16 @@ +package bitwise_and_of_numbers_range; + +public class BitwiseANDofNumbersRange { + + public class Solution { + public int rangeBitwiseAnd(int m, int n) { + int d = Integer.MAX_VALUE; + while ((m & d) != (n & d)) { + d <<= 1; + } + return m & d; + + } + } +} + diff --git a/src/main/java/bold_words_in_string/BoldWordsInString.java b/src/main/java/bold_words_in_string/BoldWordsInString.java new file mode 100644 index 0000000..dad075e --- /dev/null +++ b/src/main/java/bold_words_in_string/BoldWordsInString.java @@ -0,0 +1,37 @@ +package bold_words_in_string; + +import java.util.HashSet; +import java.util.Set; + +/** + * Created by lxie on 7/17/18. + */ +public class BoldWordsInString { + + public String boldWords(String[] words, String S) { + int n = S.length(); + String res = ""; + Set bold = new HashSet<>(); + for (String word : words) { + int len = word.length(); + for (int i = 0; i <= n - len; ++i) { + if (S.charAt(i) == word.charAt(0) && S.substring(i, i+len).compareTo(word) == 0) { + for (int j = i; j < i + len; ++j) bold.add(j); + } + } + } + for (int i = 0; i < n; ++i) { + if (bold.contains(i) && !bold.contains(i - 1)) res += ""; + res += S.charAt(i); + if (bold.contains(i) && !bold.contains(i + 1)) res += ""; + } + return res; + } + + public static void main(String[] args) { + BoldWordsInString bs = new BoldWordsInString(); + String[] words = {"ab", "bc"}; + System.out.println(bs.boldWords(words, "aabcd")); + + } +} diff --git a/src/main/java/bomb_enemy/BombEnemy.java b/src/main/java/bomb_enemy/BombEnemy.java new file mode 100644 index 0000000..b87daac --- /dev/null +++ b/src/main/java/bomb_enemy/BombEnemy.java @@ -0,0 +1,40 @@ +package bomb_enemy; + +/** + * Created by lxie on 12/7/17. + */ +public class BombEnemy { + + public class Solution { + public int maxKilledEnemies(char[][] grid) { + if (grid == null || grid[0] == null) return 0; + int m = grid.length, n = grid[0].length, res = 0, rowCnt = 0; + int[] colCnt = new int[n]; + for (int i = 0; i < m; ++i) { + for (int j = 0; j < n; ++j) { + if (j == 0 || grid[i][j - 1] == 'W') { + rowCnt = 0; + for (int k = j; k < n && grid[i][k] != 'W'; ++k) { + rowCnt += grid[i][k] == 'E' ? 1 : 0; + } + } + if (i == 0 || grid[i - 1][j] == 'W') { + colCnt[j] = 0; + for (int k = i; k < m && grid[k][j] != 'W'; ++k) { + colCnt[j] += grid[k][j] == 'E' ? 1 : 0; + } + } + if (grid[i][j] == '0') { + res = Integer.max(res, rowCnt + colCnt[j]); + } + } + } + return res; + + } + } + + public static class UnitTest { + + } +} diff --git a/src/main/java/boundary_of_binary_tree/BoundaryBinaryTree.java b/src/main/java/boundary_of_binary_tree/BoundaryBinaryTree.java new file mode 100644 index 0000000..7bb0519 --- /dev/null +++ b/src/main/java/boundary_of_binary_tree/BoundaryBinaryTree.java @@ -0,0 +1,41 @@ +package boundary_of_binary_tree; + +import common.TreeNode; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by lxie on 9/15/18. + */ +public class BoundaryBinaryTree { + + public class Solution { + + public List boundaryOfBinaryTree(TreeNode root) { + List res = new ArrayList<>(); + if (root == null) return res; + helper(root.left, true, false, res); + helper(root.right, false, true, res); + return res; + } + void helper(TreeNode node, boolean leftbd, boolean rightbd, List res) { + if (node == null) return; + if (node.left == null && node.right == null) { + res.add(node.val); + return; + } + if (leftbd) res.add(node.val); + helper(node.left, leftbd && node.left != null, rightbd && node.right == null, res); + helper(node.right, leftbd && node.left == null, rightbd && node.right != null, res); + if (rightbd) res.add(node.val); + } + } + + public class UnitTest { + + + } + + +} diff --git a/src/main/java/brick_wall/BrickWall.java b/src/main/java/brick_wall/BrickWall.java new file mode 100644 index 0000000..976c434 --- /dev/null +++ b/src/main/java/brick_wall/BrickWall.java @@ -0,0 +1,38 @@ +package brick_wall; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Created by lxie on 10/1/18. + */ +public class BrickWall { + + public class Solution { + + public int leastBricks(List> wall) { + int mx = 0; + Map m = new HashMap<>(); + for (List a : wall) { + int sum = 0; + for (int i = 0; i < a.size() - 1; ++i) { + sum += a.get(i); + if (m.containsKey(sum)) + m.put(sum, m.get(sum)+1); + else + m.put(sum, 1); + mx = Math.max(mx, m.get(sum)); + } + } + return wall.size() - mx; + } + } + + public class UnitTest { + + + + } + +} diff --git a/src/main/java/bulls_and_cows/BullAndCows.java b/src/main/java/bulls_and_cows/BullAndCows.java new file mode 100644 index 0000000..622337f --- /dev/null +++ b/src/main/java/bulls_and_cows/BullAndCows.java @@ -0,0 +1,29 @@ +package bulls_and_cows; + +/** + * Created by lxie on 6/21/18. + */ +public class BullAndCows { + + public class Solution { + + public String getHint(String secret, String guess) { + int bulls = 0, cows = 0; + int[] m = new int[256]; + for (int i = 0; i < secret.length(); ++i) { + if (secret.charAt(i) == guess.charAt(i)) ++bulls; + else { + if (m[secret.charAt(i)]++ < 0) ++cows; + if (m[guess.charAt(i)]-- > 0) ++ cows; + } + } + return Integer.toString(bulls)+ "A" + Integer.toString(cows) + "B"; + } + } + + public class UnitTest { + + + } + +} diff --git a/src/main/java/burst_balloons/BurstBalloons.java b/src/main/java/burst_balloons/BurstBalloons.java new file mode 100644 index 0000000..ba7b6ee --- /dev/null +++ b/src/main/java/burst_balloons/BurstBalloons.java @@ -0,0 +1,38 @@ +package burst_balloons; + +/** + * Created by lxie on 1/22/18. + */ +public class BurstBalloons { + + public class Solution { + public int maxCoins(int[] nums) { + if(nums == null || nums.length == 0) return 0; + int n = nums.length; + //开数组到n+2是为了保证k-1 k+1不溢出 + int[][] dp = new int[n+2][n+2]; + for(int i=1;i<=n;i++){ + int left = i-2 >= 0?nums[i-2]:1; + int right = i < n?nums[i]:1; + dp[i][i] = left*nums[i-1]*right; + } + for(int len = 2;len<=n;len++){ + for(int i=1;i+len-1<=n;i++){ + int j = i+len-1; + int left = i-2 >= 0?nums[i-2]:1; + int right = j < n?nums[j]:1; + dp[i][j] = Integer.MIN_VALUE; + for(int k=i;k<=j;k++){ + dp[i][j] = Math.max(dp[i][j], dp[i][k-1]+dp[k+1][j]+left*right*nums[k-1]); + } + } + } + return dp[1][n]; + } + } + + public static class UniTest { + + } + +} diff --git a/src/main/java/climbing_stairs/ClimbingStairs.java b/src/main/java/climbing_stairs/ClimbingStairs.java index cd60f35..d32efe1 100644 --- a/src/main/java/climbing_stairs/ClimbingStairs.java +++ b/src/main/java/climbing_stairs/ClimbingStairs.java @@ -4,15 +4,15 @@ public class ClimbingStairs { public class Solution { public int climbStairs(int n) { - int f1 = 1; - int f2 = 1; - for (int i = 2; i <= n; i++) { - int temp = f1 + f2; - f1 = f2; - f2 = temp; + if (n <= 1) return 1; + int[] dp = new int[n]; + dp[0] = 1; dp[1] = 2; + for (int i = 2; i < n; ++i) { + dp[i] = dp[i - 1] + dp[i - 2]; } - return f2; + return dp[n-1]; } + } public static class UnitTest { diff --git a/src/main/java/clone_graph/CloneGraph.java b/src/main/java/clone_graph/CloneGraph.java index 244f805..bad5c20 100644 --- a/src/main/java/clone_graph/CloneGraph.java +++ b/src/main/java/clone_graph/CloneGraph.java @@ -18,7 +18,7 @@ private UndirectedGraphNode cloneGraph(UndirectedGraphNode node, } newNode.neighbors.add(newNeighbor); } - return node; + return newNode; } public UndirectedGraphNode cloneGraph(UndirectedGraphNode node) { diff --git a/src/main/java/closest_bst_value/ClosestBSTValue.java b/src/main/java/closest_bst_value/ClosestBSTValue.java new file mode 100644 index 0000000..73bd730 --- /dev/null +++ b/src/main/java/closest_bst_value/ClosestBSTValue.java @@ -0,0 +1,36 @@ +package closest_bst_value; + +import common.TreeNode; + +/** + * Created by lxie on 6/11/18. + */ +public class ClosestBSTValue { + + public class Solution { + + public int closestValue(TreeNode root, double target) { + int res = root.val; + while (root != null) { + if (Math.abs(res - target) >= Math.abs(root.val - target)) { + res = root.val; + } + root = target < root.val ? root.left : root.right; + } + return res; + } + + int closestValueRecursive(TreeNode root, double target) { + int a = root.val; + TreeNode t = target < a ? root.left : root.right; + if (t == null) return a; + int b = closestValue(t, target); + return Math.abs(a - target) < Math.abs(b - target) ? a : b; + } + } + + public class UnitTest { + + } + +} diff --git a/src/main/java/closest_bst_value_ii/ClosestBSTValueII.java b/src/main/java/closest_bst_value_ii/ClosestBSTValueII.java new file mode 100644 index 0000000..7c34964 --- /dev/null +++ b/src/main/java/closest_bst_value_ii/ClosestBSTValueII.java @@ -0,0 +1,66 @@ +package closest_bst_value_ii; + +import common.TreeNode; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by lxie on 6/13/18. + */ +public class ClosestBSTValueII { + + public class Solution { + + public List closestKValues(TreeNode root, double target, int k) { + List values = new ArrayList<>(); + + traverse(root, values); + + int i = 0, n = values.size(); + for (; i < n; i++) { + if (values.get(i) >= target) { + break; + } + } + + if (i >= n) { + return values.subList(n - k, n); + } + + int left = i - 1, right = i; + List result = new ArrayList<>(); + for (i = 0; i < k; i++) { + if (left >= 0 && (right >= n || target - values.get(left) < values.get(right) - target)) { + result.add(values.get(left)); + left--; + } else { + result.add(values.get(right)); + right++; + } + } + + return result; + } + + private void traverse(TreeNode root, List values) { + if (root == null) { + return; + } + + traverse(root.left, values); + values.add(root.val); + traverse(root.right, values); + } + + + + + } + + public class UnitTest { + + + } + +} diff --git a/src/main/java/coin_change/CoinChange.java b/src/main/java/coin_change/CoinChange.java new file mode 100644 index 0000000..4c543f1 --- /dev/null +++ b/src/main/java/coin_change/CoinChange.java @@ -0,0 +1,27 @@ +package coin_change; + +/** + * Created by lxie on 11/15/17. + */ +public class CoinChange { + public class Solution { + public int coinChange(int[] coins, int amount) { + int[] dp = new int[amount+1]; + for(int i=0; i< dp.length; ++i) dp[i] = amount+1; + dp[0] = 0; + for (int i = 1; i <= amount; ++i) { + for (int j = 0; j < coins.length; ++j) { + if (coins[j] <= i) { + dp[i] = Math.min(dp[i], dp[i - coins[j]] + 1); + } + } + } + return dp[amount] > amount ? -1 : dp[amount]; + } + + } + + public static class UnitTest { + + } +} diff --git a/src/main/java/coin_change_ii/CoinChangeII.java b/src/main/java/coin_change_ii/CoinChangeII.java new file mode 100644 index 0000000..8766cbb --- /dev/null +++ b/src/main/java/coin_change_ii/CoinChangeII.java @@ -0,0 +1,28 @@ +package coin_change_ii; + +/** + * Created by lxie on 11/16/17. + */ +public class CoinChangeII { + + public class Solution { + public int change(int amount, int[] coins) { + int[] dp = new int[amount + 1]; + dp[0] = 1; + for (int coin : coins) { + for (int i = coin; i <= amount; ++i) { + dp[i] += dp[i - coin]; + } + } + return dp[amount]; + } + + } + + public static class UnitTest { + + } + + + +} diff --git a/src/main/java/coin_path/CoinPath.java b/src/main/java/coin_path/CoinPath.java new file mode 100644 index 0000000..39f05e6 --- /dev/null +++ b/src/main/java/coin_path/CoinPath.java @@ -0,0 +1,46 @@ +package coin_path; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * Created by lxie on 9/21/18. + */ +public class CoinPath { + + public class Solution { + + public List cheapestJump(int[] A, int B) { + List res = new ArrayList<>(); + if (A[A.length-1] == -1) return res; + int n = A.length; + int[] dp = new int[n]; Arrays.fill(dp, Integer.MAX_VALUE); + int[] pos = new int[n]; Arrays.fill(dp, -1); + dp[n - 1] = A[n - 1]; + for (int i = n - 2; i >= 0; --i) { + if (A[i] == -1) continue; + for (int j = i + 1; j <= Math.min(i + B, n - 1); ++j) { + if (dp[j] == Integer.MAX_VALUE) continue; + if (A[i] + dp[j] < dp[i]) { + dp[i] = A[i] + dp[j]; + pos[i] = j; + } + } + } + if (dp[0] == Integer.MAX_VALUE) return res; + for (int cur = 0; cur != -1; cur = pos[cur]) { + res.add(cur + 1); + } + return res; + } + } + + public class UnitTest { + + + + } + + +} diff --git a/src/main/java/combination_sum/CombinationSum.java b/src/main/java/combination_sum/CombinationSum.java new file mode 100644 index 0000000..a907154 --- /dev/null +++ b/src/main/java/combination_sum/CombinationSum.java @@ -0,0 +1,35 @@ +package combination_sum; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class CombinationSum { + + public class Solution { + public List> combinationSum(int[] num, int target) { + List> res = new ArrayList<>(); + List out = new ArrayList<>(); + Arrays.sort(num); + combinationSum2DFS(num, target, 0, out, res); + return res; + } + + private void combinationSum2DFS(int[] num, int target, int start, List out, List> res) { + if (target < 0) return; + else if (target == 0) res.add(new ArrayList<>(out)); + else { + for (int i = start; i < num.length; ++i) { + if (i > start && num[i] == num[i - 1]) continue; + out.add(num[i]); + combinationSum2DFS(num, target - num[i], i, out, res); // allows duplicate + out.remove(out.size()-1); + } + } + } + } + + public static class UnitTest { + + } +} diff --git a/src/main/java/combination_sum_IV/CombinationSumIV.java b/src/main/java/combination_sum_IV/CombinationSumIV.java new file mode 100644 index 0000000..f976d33 --- /dev/null +++ b/src/main/java/combination_sum_IV/CombinationSumIV.java @@ -0,0 +1,29 @@ +package combination_sum_IV; + +import java.util.Arrays; + +/** + * Created by lxie on 9/14/17. + */ +public class CombinationSumIV { + + class Solution { + public int combinationSum4(int[] nums, int target) { + int[] dp = new int[target+1]; + dp[0] = 1; + Arrays.sort(nums); + for (int i = 1; i <= target; i++) { + for(int a : nums){ + if (i < a) break; + dp[i] += dp[i-a]; + } + } + return dp[target]; + } + } + + public static void main(String[] args) { + System.out.println("this is for test"); + } + +} diff --git a/src/main/java/combination_sum_ii/CombinationSumII.java b/src/main/java/combination_sum_ii/CombinationSumII.java new file mode 100644 index 0000000..5cdffb9 --- /dev/null +++ b/src/main/java/combination_sum_ii/CombinationSumII.java @@ -0,0 +1,36 @@ +package combination_sum_ii; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class CombinationSumII { + + public class Solution { + public List> combinationSum2(int[] num, int target) { + List> res = new ArrayList<>(); + List out = new ArrayList<>(); + Arrays.sort(num); + combinationSum2DFS(num, target, 0, out, res); + return res; + } + + private void combinationSum2DFS(int[] num, int target, int start, List out, List> res) { + if (target < 0) return; + else if (target == 0) res.add(new ArrayList<>(out)); + else { + for (int i = start; i < num.length; ++i) { + if (i > start && num[i] == num[i - 1]) continue; + out.add(num[i]); + combinationSum2DFS(num, target - num[i], i + 1, out, res); // no duplicate + out.remove(out.size()-1); + } + } + } + + } + + public static class UnitTest { + + } +} diff --git a/src/main/java/combination_sum_iii/CombinationSumIII.java b/src/main/java/combination_sum_iii/CombinationSumIII.java new file mode 100644 index 0000000..c362e90 --- /dev/null +++ b/src/main/java/combination_sum_iii/CombinationSumIII.java @@ -0,0 +1,39 @@ +package combination_sum_iii; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by lxie on 2/8/18. + */ +public class CombinationSumIII { + + public static class Solution { + // public List> res = new ArrayList<>(); + + public List> combinationSum3(int k, int n) { + List> res = new ArrayList<>(); + List out = new ArrayList<>(); + combinationSum3DFS(k, n, 1, out, res); + return res; + } + void combinationSum3DFS(int k, int n, int level, List out, List> res) { + if (n < 0 || out.size() > k) return; + if (n == 0 && out.size() == k) + res.add(new ArrayList(out)); + for (int i = level; i <= 9; ++i) { + out.add(i); + combinationSum3DFS(k, n - i, i + 1, out, res); + out.remove(out.size()-1); + } + } + } + + public static void main(String[] args) { + Solution s = new Solution(); + List> res = s.combinationSum3(3, 7); + System.out.println(res); + } + + +} diff --git a/src/main/java/combinations/Combinations.java b/src/main/java/combinations/Combinations.java index 4839652..c264f62 100644 --- a/src/main/java/combinations/Combinations.java +++ b/src/main/java/combinations/Combinations.java @@ -1,31 +1,30 @@ package combinations; -import java.util.ArrayDeque; import java.util.ArrayList; +import java.util.List; public class Combinations { public class Solution { - private void search(int start, int end, int k, - ArrayDeque queue, ArrayList> ans) { - if (k == 0) { - ans.add(new ArrayList(queue)); - return; - } + public List> combine(int n, int k) { + List > res = new ArrayList<>(); + List out = new ArrayList<>(); + combineDFS(n, k, 1, out, res); + return res; + } - for (int i = start; i <= end - k + 1; i++) { - queue.offerLast(i); - search(i + 1, end, k - 1, queue, ans); - queue.removeLast(); + private void combineDFS(int n, int k, int level, List out, List > res) { + if (out.size() == k) res.add(new ArrayList<>(out)); + else { + for (int i = level; i <= n; ++i) { + out.add(i); + combineDFS(n, k, i + 1, out, res); + out.remove(out.size()-1); + } } } - public ArrayList> combine(int n, int k) { - ArrayList> ans = new ArrayList>(); - search(1, n, k, new ArrayDeque(), ans); - return ans; - } } public static class UnitTest { diff --git a/src/main/java/common/Interval.java b/src/main/java/common/Interval.java index 1341f7d..3fe3ee5 100644 --- a/src/main/java/common/Interval.java +++ b/src/main/java/common/Interval.java @@ -1,6 +1,6 @@ package common; -public class Interval { +public final class Interval { public int start; public int end; @@ -13,4 +13,26 @@ public Interval(int s, int e) { start = s; end = e; } + + @Override + public String toString() { + return "[" + start + ", " + end + "]"; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Interval that = (Interval) o; + return start == that.start && end == that.end; + } + + @Override + public int hashCode() { + return 31 * start + end; + } } diff --git a/src/main/java/common/NestedInteger.java b/src/main/java/common/NestedInteger.java new file mode 100644 index 0000000..77ec2e3 --- /dev/null +++ b/src/main/java/common/NestedInteger.java @@ -0,0 +1,19 @@ +package common; + +import java.util.List; + +/** + * Created by lxie on 1/27/18. + */ +public interface NestedInteger { + // @return true if this NestedInteger holds a single integer, rather than a nested list. + public boolean isInteger(); + + // @return the single integer that this NestedInteger holds, if it holds a single integer + // Return null if this NestedInteger holds a nested list + public Integer getInteger(); + + // @return the nested list that this NestedInteger holds, if it holds a nested list + // Return null if this NestedInteger holds a single integer + public List getList(); +} diff --git a/src/main/java/common/Pair.java b/src/main/java/common/Pair.java new file mode 100644 index 0000000..d63f0d5 --- /dev/null +++ b/src/main/java/common/Pair.java @@ -0,0 +1,13 @@ +package common; + +import java.util.AbstractMap; +import java.util.Map; + +public class Pair { + + // Return a map entry (key-value pair) from the specified values + public static Map.Entry of(T first, U second) { + return new AbstractMap.SimpleEntry<>(first, second); + } + +} \ No newline at end of file diff --git a/src/main/java/common/Point.java b/src/main/java/common/Point.java new file mode 100644 index 0000000..f25349d --- /dev/null +++ b/src/main/java/common/Point.java @@ -0,0 +1,16 @@ +package common; + +class Point { + public int x; + public int y; + + public Point() { + x = 0; + y = 0; + } + + public Point(int a, int b) { + x = a; + y = b; + } +} \ No newline at end of file diff --git a/src/main/java/compare_version_numbers/CompareVersionNumbers.java b/src/main/java/compare_version_numbers/CompareVersionNumbers.java new file mode 100644 index 0000000..0a87899 --- /dev/null +++ b/src/main/java/compare_version_numbers/CompareVersionNumbers.java @@ -0,0 +1,42 @@ +package compare_version_numbers; + +public class CompareVersionNumbers { + + public class Solution { + public int compareVersion(String version1, String version2) { + String[] splits1 = version1.split("\\."); + String[] splits2 = version2.split("\\."); + int i = 0; + for (; i < splits1.length && i < splits2.length; i++) { + int v1 = Integer.parseInt(splits1[i]); + int v2 = Integer.parseInt(splits2[i]); + if (v1 > v2) { + return 1; + } else if (v1 < v2) { + return -1; + } + } + if (i == splits1.length) { + for (int j = i; j < splits2.length; j++) { + int v = Integer.parseInt(splits2[j]); + if (v != 0) { + return -1; + } + } + } else { + for (int j = i; j < splits1.length; j++) { + int v = Integer.parseInt(splits1[j]); + if (v != 0) { + return 1; + } + } + } + return 0; + } + } + + public static class UnitTest { + + } +} + diff --git a/src/main/java/compressed_string_iterator/CompressedStringIterator.java b/src/main/java/compressed_string_iterator/CompressedStringIterator.java new file mode 100644 index 0000000..84a1ff1 --- /dev/null +++ b/src/main/java/compressed_string_iterator/CompressedStringIterator.java @@ -0,0 +1,39 @@ +package compressed_string_iterator; + +/** + * Created by lxie on 7/18/18. + */ +public class CompressedStringIterator { + + private static String s; + private int n = 0, i = 0, cnt = 0; + private char c; + + public CompressedStringIterator(String compressedString) { + s = compressedString; + n = s.length(); + c = ' '; + } + + public char next() { + if (hasNext()) { + --cnt; + return c; + } + return ' '; + } + + public boolean hasNext() { + if (cnt > 0) return true; + if (i >= n) return false; + c = s.charAt(i++); + while (i < n && s.charAt(i) >= '0' && s.charAt(i) <= '9') { + cnt = cnt * 10 + s.charAt(i++) - '0'; + } + return true; + } +} + + + + diff --git a/src/main/java/concurrent_hash_table/ConcurrentHashTable.java b/src/main/java/concurrent_hash_table/ConcurrentHashTable.java new file mode 100644 index 0000000..eeed8f2 --- /dev/null +++ b/src/main/java/concurrent_hash_table/ConcurrentHashTable.java @@ -0,0 +1,30 @@ +package concurrent_hash_table; + +public interface ConcurrentHashTable +{ + /* + * Concurrency setting, i.e., number of locks. + */ + public void setConcurrency(int numLocks); + + /* + * Get the value by key + * + */ + public V get(K key); + + /* + * Put the item to the hash table + */ + public void put(K key, V value); + + /* + * Remove an item from the hash table + */ + public void remove(K key); + + /* + * Get current total number of entries + */ + public int getTotal(); +} diff --git a/src/main/java/concurrent_hash_table/MyConcurrentHashTable.java b/src/main/java/concurrent_hash_table/MyConcurrentHashTable.java new file mode 100644 index 0000000..e3c4a8e --- /dev/null +++ b/src/main/java/concurrent_hash_table/MyConcurrentHashTable.java @@ -0,0 +1,211 @@ +package concurrent_hash_table; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.concurrent.locks.ReentrantLock; + +/** + * @author l.xie@salesforce.com + * @version $Revision$ + */ +public class MyConcurrentHashTable implements ConcurrentHashTable { + /** + * Total number of buckets. This is the concurrency setting. + */ + private static int _numBuckets = 1000; //default concurrency + /** + * Array list to store the hash buckets. We use an ArrayList instead of an array so that we can + * use generics. We explicitly use ArrayList (instead of List) because this needs to support + * efficient index based access. Similarly, we use LinkedList for the buckets, since they must + * support efficient insert and delete. + *

+ * Alternatively we could use "Node[] _buckets = new Node(_numBuckets);", but that + * requires an unchecked cast for the return value in "get". Note that you cannot create + * Node[] _buckets = new Node[_numBuckets] - that will not compile (generics error). + */ + private final ArrayList> _buckets = new ArrayList>(_numBuckets); + + /** + * Array of ReentrantLocks used to guard the hashtable buckets (LinkedLists) from concurrent + * access. The lock array is the same size as the bucket array, but that is not strictly necessary. + * Using fewer locks would simply mean more than one bucket is guarded by each lock + *

+ * We could allow a concurrency factor to be passed to the constructor and and calculate + * an appropriate number of locks from that, but do not do that here for simplicity sake. + */ + private final ArrayList _bucketLocks = new ArrayList(_numBuckets); + + /** + * Create a new, empty hashtable. + */ + public MyConcurrentHashTable(int concurrency) { + // Initialize the buckets and locks. + // We must initialize the _buckets or else _buckets.size() is zero and we get + // OutOfBoundsExceptions. If we used an array instead of ArrayList then we would not have to + // initialize _buckets (since arrays elements automatically initialize to null). + setConcurrency(concurrency); + for (int i = 0; i < _numBuckets; i++) { + _bucketLocks.add(new ReentrantLock()); + _buckets.add(null); + } + } + + @Override + public void setConcurrency(int numLocks) { + _numBuckets = numLocks; + } + + /** + * Return the value associated with the given key. If the key does not exist then return null. + * + * @param key key to lookup + * @return value associated with key; null if none exists + * @throws NullPointerException if key is null + */ + @Override + public V get(K key) { + try { + // Lock and get the bucket for this key + LinkedList bucket = lockAndReturnBucket(key); + + // Iterate through the bucket looking for the key. If we find it, return the value. + for (Node node : bucket) { + if (node.key.equals(key)) { + return node.value; + } + } + + // We did not find the key. Return null. + return null; + } finally { + // Unlock the bucket + unlockBucket(key); + } + } + + /** + * Add the key-value pair to the hashtable. If the key already exists, it's value will be + * overwritten. Key and value must be non-null. + * + * @param key the key + * @param value the value + * @throws NullPointerException if key or value are null + */ + @Override + public void put(K key, V value) { + try { + // Lock and get the bucket for this key + LinkedList bucket = lockAndReturnBucket(key); + + // Iterate through the bucket looking for the key. If we find it then replace the value and return. + for (Node node : bucket) { + if (node.key.equals(key)) { + node.value = value; + return; + } + } + + // We did not find the key already in the bucket. Add it and return. + bucket.add(new Node(key, value)); + } finally { + // Unlock the bucket + unlockBucket(key); + } + } + + /** + * Obtain a lock on the bucket for the given key, then return the bucket. All calls + * to this method must be followed by a call to {@see #unlockBucket(K)} in a + * {@code finally} block. + * + * @param key the desired bucket's key + */ + private LinkedList lockAndReturnBucket(K key) { + // Calculate the hash code for the key, then convert that to the index within the + // buckets List. + int hashCode = key.hashCode(); + int bucketIndex = Math.abs(hashCode % _numBuckets); + + _bucketLocks.get(bucketIndex).lock(); + + // Find the LinkedList in the buckets array. If we haven't initialized that bucket yet + // then create a new LinkedList and put it at the correct spot in the list. + LinkedList bucket = _buckets.get(bucketIndex); + if (bucket == null) { + bucket = new LinkedList(); + _buckets.set(bucketIndex, bucket); + } + + // Return the LinkedList bucket + return bucket; + } + + /** + * Unlock a bucket that was previously locked with a call to {@see #lockAndReturnBucket(K)}. + * + * @param key the bucket's key + */ + private void unlockBucket(K key) { + // Calculate the hash code for the key, then convert that to the index within the + // buckets List. + int hashCode = key.hashCode(); + int bucketIndex = Math.abs(hashCode % _numBuckets); + + _bucketLocks.get(bucketIndex).unlock(); + } + + /** + * Inner class to represent a key-value pair in the LinkedList "buckets". + */ + public class Node { + K key; + V value; + + private Node(K key, V value) { + this.key = key; + this.value = value; + } + } + + // The remove method, which is not included in the interface, is shown below. The candidate does not need to write this method. I am adding it because I already have it written, and we may decide to add it to the interface in the future. + /** + * Remove the given key (and its associated value) from this Hashtable. + * + * @param key key to lookup + * @throws NullPointerException if key is null + */ + @Override + public void remove(K key) { + try { + // Lock and get the bucket for this key + LinkedList bucket = lockAndReturnBucket(key); + + // Iterate over the bucket looking for the key. If we find it, remove it from the bucket. + // Notice that we use an explicit iterator so that we may call ".remove" on the iterator and + // remove the item. + Iterator bucketIterator = bucket.iterator(); + while (bucketIterator.hasNext()) { + Node node = bucketIterator.next(); + if (node.key.equals(key)) { + bucketIterator.remove(); + return; + } + } + } finally { + // Unlock the bucket + unlockBucket(key); + } + } + + @Override + public int getTotal() { + int total = 0; + System.out.println("stats in hash table"); + for (int i=0; i<_buckets.size(); ++i) { + System.out.println(i + " : " + _buckets.get(i).size()); + total += _buckets.get(i).size(); + } + return total; + } +} diff --git a/src/main/java/concurrent_hash_table/MyConcurrentHashTableUnitTest.java b/src/main/java/concurrent_hash_table/MyConcurrentHashTableUnitTest.java new file mode 100644 index 0000000..4217552 --- /dev/null +++ b/src/main/java/concurrent_hash_table/MyConcurrentHashTableUnitTest.java @@ -0,0 +1,235 @@ +package concurrent_hash_table; + +import org.junit.Assert; +import org.junit.Test; + +import java.time.Duration; +import java.time.Instant; +import java.util.*; +import java.util.concurrent.ThreadLocalRandom; + +public class MyConcurrentHashTableUnitTest { + private static final int MAX_ENTRIES = 1000000; + private static final int NUM_THREADS = 100; + private static MyConcurrentHashTable table; + private static Map result= new HashMap<>(); + + public MyConcurrentHashTableUnitTest() { + } + + @Test + public void testPut(){ // single thread puts + table = new MyConcurrentHashTable(1000); + for (int i = 0; i < MAX_ENTRIES; i++) { + int randomNum = ThreadLocalRandom.current().nextInt(0, Integer.MAX_VALUE); + String randomString = generateRandomString(50); + table.put(randomNum, randomString); + result.put(randomNum, randomString); + System.out.println("<" + randomNum + ", " + randomString + ">"); + } + Assert.assertEquals(result.size(), table.getTotal()); + } + + @Test + public void testGet(){ // single thread puts/gets + int hit_count = 0; + testPut(); + for (Map.Entry entry: result.entrySet()) { + String value = (String) table.get(entry.getKey()); + if (value != null && value.equals(entry.getValue())) { + hit_count++; + } + System.out.println("<" + entry.getKey() + "-> " + value + ">"); + } + Assert.assertEquals(result.size(), hit_count); + table.getTotal(); + } + + @Test + public void testRemove() { // single thread remove + testPut(); + for (Map.Entry entry : result.entrySet()) { + table.remove(entry.getKey()); + } + Assert.assertEquals(0, table.getTotal()); + } + + @Test + public void testMultiPutLowBuckets(){ // test multi-thread puts on low buckets + table = new MyConcurrentHashTable(200); + long latency = multiputTest(); + assert(latency > 40000); + } + + @Test + public void testMultiPutDefaultBuckets(){ // test multi-thread puts on default buckets + table = new MyConcurrentHashTable(1000); + long latency = multiputTest(); + assert(latency < 20000); + } + + @Test + public void testMultiPutMoreBuckets(){ // test multi-thread puts on more buckets + table = new MyConcurrentHashTable(5000); + long latency = multiputTest(); + assert(latency < 15000); + } + + @Test + public void testMultiPutMaxBuckets(){ // test multi-thread puts on max buckets + table = new MyConcurrentHashTable(10000); + long latency = multiputTest(); + assert(latency < 13000); + } + + @Test + public void testMultiPutAndGetDefaultBuckets(){ // test multi-thread puts and gets on default buckets + table = new MyConcurrentHashTable(10000); + long latency = multiputAndGetTest(); + assert(latency < 30000); + } + + private long multiputTest() { + Instant start = Instant.now(); + List threads = new ArrayList<>(); + for (int i=0; i threads = new ArrayList<>(); + for (int i=0; i"); + } + } catch (Exception e) { + // Throwing an exception + System.out.println("Exception is caught"); + } + } +} + +// Multi Gets thread creation by extending +// the Thread class +class MultithreadGet extends Thread { + int threadId = 0; + int batchSize = 0; + MyConcurrentHashTable table; + + public MultithreadGet(MyConcurrentHashTable table, int batchSize, int id) { + this.threadId = id; + this.batchSize = batchSize; + this.table = table; + } + + public void run() { + try { + // Displaying the thread that is running + System.out.println("Thread " + threadId + " is running"); + for (int i = 0; i < batchSize; i++) { + int randomNum = ThreadLocalRandom.current().nextInt(0, Integer.MAX_VALUE); + //String randomString = MyConcurrentHashTableUnitTest.generateRandomString(50); + String value = (String) table.get(randomNum); + //keys.add(randomNum); + System.out.println("<" + randomNum + "-> " + value + ">"); + } + } catch (Exception e) { + // Throwing an exception + System.out.println("Exception is caught"); + } + } +} \ No newline at end of file diff --git a/src/main/java/concurrent_hash_table/readme b/src/main/java/concurrent_hash_table/readme new file mode 100644 index 0000000..b60ce89 --- /dev/null +++ b/src/main/java/concurrent_hash_table/readme @@ -0,0 +1,52 @@ +Implement a concurrent hash table + +We need to implement a concurrent hash table. This implementation should not use any of the existing HashMap library in Java. It should implement a hash table from scratch (given the interface). + +We need to implement the following methods for the hash table + +Get, Put, Remove + +And, we need to design our approach to achieve the maximum concurrency and scalability while doing these operations. This means that, we should not block other operations if they are not operating on the same entry. This also means that, we should save system resource (e.g., locks, semaphores) in order to be scalable. + + +Output: A JAVA class implementation of the concurrent hash table. An analysis on why you choose the approach and how do you optimize the concurrency and achieve scalability. + + +Tests: write a test class to verify the implementation. The test should include: + +1. single thread hash-table operations +2. multiple threads hash-table operations - on different record(s) +3. multiple threads hash-table operations - on same record(s) +4. different settings/configs for the hash table +5. exception handlings + + +Interface to implement +/* + * Concurrent hash table implementation. + * Expected to be used in a multi-threading env + */ +public interface ConcurrentHashTable +{ + /* + * Concurrency setting, i.e., number of locks. + */ + public void init(int numLocks); + + /* + * Get the value by key + * + */ + public V get(K key); + + /* + * Put the item to the hash table + */ + public void put(K key, V value); + + /* + * Remove an item from the hash table + */ + public void remove(K key); +} + diff --git a/src/main/java/connected_components_in_undirected_graph/ConnectedComponentsGraph.java b/src/main/java/connected_components_in_undirected_graph/ConnectedComponentsGraph.java new file mode 100644 index 0000000..b104a57 --- /dev/null +++ b/src/main/java/connected_components_in_undirected_graph/ConnectedComponentsGraph.java @@ -0,0 +1,52 @@ +package connected_components_in_undirected_graph; + +import java.util.*; + +/** + * Created by lxie on 1/10/18. + */ +public class ConnectedComponentsGraph { + + class Solution { + public int NumberOfConnectedComponents(int n, int[][] edges) { + if (n == 0) return 0; + int res = 0; + List> g = new ArrayList<>(n); + List v = new ArrayList<>(n); + for (int i = 0; i < n; ++i) { + g.add(new HashSet<>()); + v.add(false); + } + for (int[] edge : edges) { + g.get(edge[0]).add(edge[1]); + g.get(edge[1]).add(edge[0]); + } + + for (int i = 0; i < n; ++i) { + if (v.get(i) == false) { + ++res; + dfs(g, v, i); + } + } + return res; + } + + void dfs(List> g, List v, int i) { + if (v.get(i) == true) return; + v.set(i, true); + for (int j : g.get(i)) { + dfs(g, v, j); + } + } + + + } + + public static class UnitTest { + + } + + + + +} diff --git a/src/main/java/construct_binary_tree_from_inorder_and_postorder_traversal/ConstructBinaryTreefromInorderandPostorderTraversal.java b/src/main/java/construct_binary_tree_from_inorder_and_postorder_traversal/ConstructBinaryTreefromInorderandPostorderTraversal.java index 60b9cbb..760c5b3 100644 --- a/src/main/java/construct_binary_tree_from_inorder_and_postorder_traversal/ConstructBinaryTreefromInorderandPostorderTraversal.java +++ b/src/main/java/construct_binary_tree_from_inorder_and_postorder_traversal/ConstructBinaryTreefromInorderandPostorderTraversal.java @@ -1,35 +1,29 @@ package construct_binary_tree_from_inorder_and_postorder_traversal; -import java.util.HashMap; -import java.util.Map; - import common.TreeNode; +import java.util.List; + public class ConstructBinaryTreefromInorderandPostorderTraversal { public class Solution { - private TreeNode buildTree(Map inorder, int b1, - int[] postorder, int b2, int len) { - if (len == 0) { - return null; - } - TreeNode node = new TreeNode(postorder[b2 + len - 1]); - int i = inorder.get(node.val); - node.left = buildTree(inorder, b1, postorder, b2, i - b1); - node.right = buildTree(inorder, i + 1, postorder, b2 + i - b1, len - - i + b1 - 1); - return node; + public TreeNode buildTree(List inorder, List postorder) { + return buildTree(inorder, 0, inorder.size() - 1, postorder, 0, postorder.size() - 1); } - public TreeNode buildTree(int[] inorder, int[] postorder) { - assert inorder != null && postorder != null - && inorder.length == postorder.length; - Map inorderNodes = new HashMap(); - for (int i = 0; i < inorder.length; i++) { - inorderNodes.put(inorder[i], i); + private TreeNode buildTree(List inorder, int iLeft, int iRight, + List postorder, int pLeft, int pRight) { + if (iLeft > iRight || pLeft > pRight) return null; + TreeNode cur = new TreeNode(postorder.get(pRight)); + int i = 0; + for (i = iLeft; i < inorder.size(); ++i) { + if (inorder.get(i) == cur.val) break; } - return buildTree(inorderNodes, 0, postorder, 0, inorder.length); + cur.left = buildTree(inorder, iLeft, i - 1, postorder, pLeft, pLeft + i - iLeft - 1); + cur.right = buildTree(inorder, i + 1, iRight, postorder, pLeft + i - iLeft, pRight - 1); + return cur; } + } public static class UnitTest { diff --git a/src/main/java/construct_binary_tree_from_preorder_and_inorder_traversal/ConstructBinaryTreefromPreorderandInorderTraversal.java b/src/main/java/construct_binary_tree_from_preorder_and_inorder_traversal/ConstructBinaryTreefromPreorderandInorderTraversal.java index d1efd84..a1e53b3 100644 --- a/src/main/java/construct_binary_tree_from_preorder_and_inorder_traversal/ConstructBinaryTreefromPreorderandInorderTraversal.java +++ b/src/main/java/construct_binary_tree_from_preorder_and_inorder_traversal/ConstructBinaryTreefromPreorderandInorderTraversal.java @@ -1,34 +1,28 @@ package construct_binary_tree_from_preorder_and_inorder_traversal; -import java.util.HashMap; -import java.util.Map; - import common.TreeNode; +import java.util.List; + public class ConstructBinaryTreefromPreorderandInorderTraversal { public class Solution { - private TreeNode buildTree(int[] preorder, int b1, - Map inorderNodes, int b2, int len) { - if (len == 0) { - return null; - } - TreeNode node = new TreeNode(preorder[b1]); - int i = inorderNodes.get(node.val); - node.left = buildTree(preorder, b1 + 1, inorderNodes, b2, i - b2); - node.right = buildTree(preorder, b1 + 1 + i - b2, inorderNodes, - i + 1, len - i + b2 - 1); - return node; + TreeNode buildTree(List preorder, List inorder) { + return buildTree(preorder, 0, preorder.size() - 1, inorder, 0, inorder.size() - 1); } - - public TreeNode buildTree(int[] preorder, int[] inorder) { - assert (preorder != null && inorder != null && preorder.length == inorder.length); - Map inorderNodes = new HashMap(); - for (int i = 0; i < inorder.length; i++) { - inorderNodes.put(inorder[i], i); + TreeNode buildTree(List preorder, int pLeft, int pRight, + List inorder, int iLeft, int iRight) { + if (pLeft > pRight || iLeft > iRight) return null; + int i = 0; + for (i = iLeft; i <= iRight; ++i) { + if (preorder.get(pLeft) == inorder.get(i)) break; } - return buildTree(preorder, 0, inorderNodes, 0, inorder.length); + TreeNode cur = new TreeNode(preorder.get(pLeft)); + cur.left = buildTree(preorder, pLeft + 1, pLeft + i - iLeft, inorder, iLeft, i - 1); + cur.right = buildTree(preorder, pLeft + i - iLeft + 1, pRight, inorder, i + 1, iRight); + return cur; } + } public static class UnitTest { diff --git a/src/main/java/contains_duplicate_ii/ContainsDuplicatesII.java b/src/main/java/contains_duplicate_ii/ContainsDuplicatesII.java new file mode 100644 index 0000000..bcfc18d --- /dev/null +++ b/src/main/java/contains_duplicate_ii/ContainsDuplicatesII.java @@ -0,0 +1,25 @@ +package contains_duplicate_ii; + +import java.util.HashMap; +import java.util.Map; + +/** + * Created by lxie on 2/13/18. + */ +public class ContainsDuplicatesII { + + public class Solution { + public boolean containsNearbyDuplicate(int[] nums, int k) { + Map m = new HashMap<>(); + for (int i = 0; i < nums.length; ++i) { + if (m.containsKey(nums[i]) && i - m.get(nums[i]) <= k) return true; + else m.put(nums[i], i); + } + return false; + } + } + + public static class UnitTest { + + } +} diff --git a/src/main/java/contains_duplicates_iii/ContainsDuplicatesIII.java b/src/main/java/contains_duplicates_iii/ContainsDuplicatesIII.java new file mode 100644 index 0000000..0a62bf8 --- /dev/null +++ b/src/main/java/contains_duplicates_iii/ContainsDuplicatesIII.java @@ -0,0 +1,50 @@ +package contains_duplicates_iii; + +import java.util.HashMap; +import java.util.Map; + +/** + * Created by lxie on 2/13/18. + */ +public class ContainsDuplicatesIII { + + public static class Solution { + + public boolean containsNearbyAlmostDuplicate(int[] nums, int k, int t) { + Map m = new HashMap<>(); + int j = 0; + for (int i = 0; i < nums.length; ++i) { + if (i - j > k && m.get(nums[j]) == j) m.remove(nums[j++]); + int[] lower = new int[1]; + boolean a = lower_bound(m, (long) nums[i] - t, lower); + if (a && Math.abs((long) lower[0] - nums[i]) <= t) return true; + m.put(nums[i], i); + } + return false; + } + + + // TODO - need a better algorithm !!! + private boolean lower_bound(Map m, long v, int[] res) { + long min_diff = Long.MAX_VALUE; + for (int key : m.keySet()) { + if (key >= v && key - v < min_diff) + min_diff = key - v; + } + if (min_diff == Long.MAX_VALUE) + return false; + else { + res[0] = (int) (v + min_diff); + return true; + } + } + } + + public static void main(String[] args) { + System.out.println("this is for test"); + Solution sol = new Solution(); + int[] a = {2147483647, -2147483647}; + boolean res = sol.containsNearbyAlmostDuplicate(a, 1, 2147483647); + System.out.println(res); + } +} diff --git a/src/main/java/contiguous_array/ContiguousArray.java b/src/main/java/contiguous_array/ContiguousArray.java new file mode 100644 index 0000000..96b507a --- /dev/null +++ b/src/main/java/contiguous_array/ContiguousArray.java @@ -0,0 +1,33 @@ +package contiguous_array; + +import java.util.HashMap; +import java.util.Map; + +/** + * Created by lxie on 10/7/18. + */ +public class ContiguousArray { + + public class Solution { + + int findMaxLength(int[] nums) { + int res = 0, n = nums.length, sum = 0; + Map m = new HashMap<>(); + m.put(0, -1); + for (int i = 0; i < n; ++i) { + sum += (nums[i] == 1) ? 1 : -1; + if (m.containsKey(sum)) { + res = Math.max(res, i - m.get(sum)); + } else { + m.put(sum, i); + } + } + return res; + } + } + + public class UnitTest { + + } + +} diff --git a/src/main/java/continuous_subarray_sum/ContinuousSubarraySum.java b/src/main/java/continuous_subarray_sum/ContinuousSubarraySum.java new file mode 100644 index 0000000..f35c7ca --- /dev/null +++ b/src/main/java/continuous_subarray_sum/ContinuousSubarraySum.java @@ -0,0 +1,34 @@ +package continuous_subarray_sum; + +import java.util.HashMap; +import java.util.Map; + +/** + * Created by lxie on 9/29/18. + */ +public class ContinuousSubarraySum { + + public class Solution { + + public boolean checkSubarraySum(int[] nums, int k) { + int n = nums.length, sum = 0; + Map m = new HashMap<>(); + m.put(0, -1); + for (int i = 0; i < n; ++i) { + sum += nums[i]; + int t = (k == 0) ? sum : (sum % k); + if (m.containsKey(t)) { + if (i - m.get(t) > 1) return true; + } else m.put(t, i); + } + return false; + } + + } + + public class UnitTest { + + + } + +} diff --git a/src/main/java/convert_sorted_list_to_binary_search_tree/ConvertSortedListtoBinarySearchTree.java b/src/main/java/convert_sorted_list_to_binary_search_tree/ConvertSortedListtoBinarySearchTree.java new file mode 100644 index 0000000..a4a56a4 --- /dev/null +++ b/src/main/java/convert_sorted_list_to_binary_search_tree/ConvertSortedListtoBinarySearchTree.java @@ -0,0 +1,33 @@ +package convert_sorted_list_to_binary_search_tree; + +import common.ListNode; +import common.TreeNode; + +public class ConvertSortedListtoBinarySearchTree { + + public class Solution { + public TreeNode sortedListToBST(ListNode head) { + if (head == null) return null; + if (head.next == null) return new TreeNode(head.val); + ListNode slow = head; + ListNode fast = head; + ListNode last = slow; + while (fast.next != null && fast.next.next != null) { + last = slow; + slow = slow.next; + fast = fast.next.next; + } + fast = slow.next; + last.next = null; + TreeNode cur = new TreeNode(slow.val); + if (head != slow) cur.left = sortedListToBST(head); + cur.right = sortedListToBST(fast); + return cur; + } + + } + + public static class UnitTest { + + } +} diff --git a/src/main/java/convex_polygon/ConvexPolygon.java b/src/main/java/convex_polygon/ConvexPolygon.java new file mode 100644 index 0000000..6474268 --- /dev/null +++ b/src/main/java/convex_polygon/ConvexPolygon.java @@ -0,0 +1,30 @@ +package convex_polygon; + +/** + * Created by lxie on 9/13/18. + */ +public class ConvexPolygon { + + public class Solution { + + public boolean isConvex(int[][] points) { + int n = points.length; long pre = 0, cur = 0; + for (int i = 0; i < n; ++i) { + int dx1 = points[(i + 1) % n][0] - points[i][0]; + int dx2 = points[(i + 2) % n][0] - points[i][0]; + int dy1 = points[(i + 1) % n][1] - points[i][1]; + int dy2 = points[(i + 2) % n][1] - points[i][1]; + cur = dx1 * dy2 - dx2 * dy1; + if (cur != 0) { // ignore 0 case + if (cur * pre < 0) return false; + else pre = cur; + } + } + return true; + } + } + + public class UnitTest { + + } +} diff --git a/src/main/java/count_and_say/CountandSay.java b/src/main/java/count_and_say/CountandSay.java index fe6d102..a5e026b 100644 --- a/src/main/java/count_and_say/CountandSay.java +++ b/src/main/java/count_and_say/CountandSay.java @@ -4,27 +4,23 @@ public class CountandSay { public class Solution { public String countAndSay(int n) { - String ans = "1"; - n--; - while (n > 0) { - n--; - StringBuilder builder = new StringBuilder(); - int count = 1; - for (int i = 1; i < ans.length(); i++) { - if (ans.charAt(i - 1) == ans.charAt(i)) { - count++; - } else { - builder.append(count); - builder.append(ans.charAt(i - 1)); - count = 1; + if (n <= 0) return ""; + String res = "1"; + while (--n != 0) { + String cur = ""; + for (int i = 0; i < res.length(); ++i) { + int cnt = 1; + while (i + 1 < res.length() && res.charAt(i) == res.charAt(i+1)) { + ++cnt; + ++i; } + cur += Integer.toString(cnt) + res.charAt(i); } - builder.append(count); - builder.append(ans.charAt(ans.length() - 1)); - ans = builder.toString(); + res = cur; } - return ans; + return res; } + } public static class UnitTest { diff --git a/src/main/java/count_complete_tree_nodes/CountCompleteTreeNode.java b/src/main/java/count_complete_tree_nodes/CountCompleteTreeNode.java new file mode 100644 index 0000000..477a3c1 --- /dev/null +++ b/src/main/java/count_complete_tree_nodes/CountCompleteTreeNode.java @@ -0,0 +1,35 @@ +package count_complete_tree_nodes; + +import common.TreeNode; + +/** + * Created by lxie on 2/14/18. + */ +public class CountCompleteTreeNode { + + public class Solution { + + public int countNodes(TreeNode root) { + int hLeft = leftHeight(root); + int hRight = rightHeight(root); + if (hLeft == hRight) return (int) Math.pow(2, hLeft) - 1; + return countNodes(root.left) + countNodes(root.right) + 1; + } + int leftHeight(TreeNode root) { // height of left-most + if (root == null) return 0; + return 1 + leftHeight(root.left); + } + int rightHeight(TreeNode root) { // height of righ-most + if (root == null) return 0; + return 1 + rightHeight(root.right); + } + + } + + public static class UnitTest { + + + } + + +} diff --git a/src/main/java/count_of_range_sum/CountOfRangeSum.java b/src/main/java/count_of_range_sum/CountOfRangeSum.java new file mode 100644 index 0000000..fb5cfa8 --- /dev/null +++ b/src/main/java/count_of_range_sum/CountOfRangeSum.java @@ -0,0 +1,44 @@ +package count_of_range_sum; + +/** + * Created by lxie on 8/29/18. + */ +public class CountOfRangeSum { + + public class Solution { + + public int countRangeSum(int[] nums, int lower, int upper) { + long[] sums = new long[nums.length+1]; + for (int i = 0; i < nums.length; ++i) { + sums[i + 1] = sums[i] + nums[i]; + } + return countAndMergeSort(sums, 0, sums.length, lower, upper); + } + + // j是第一个满足 sums[j] - sums[i] > upper 的下标 + // k是第一个满足 sums[k] - sums[i] >= lower 的下标 + // cache用于缓存merge sort结果(len=t)最后替换sums + + private int countAndMergeSort(long[] sums, int start, int end, int lower, int upper) { + if (end - start <= 1) return 0; + int mid = start + (end - start) / 2; + int cnt = countAndMergeSort(sums, start, mid, lower, upper) + countAndMergeSort(sums, mid, end, lower, upper); + int j = mid, k = mid, t = mid; + long[] cache = new long[end-start]; + for (int i = start, r = 0; i < mid; ++i, ++r) { + while (k < end && sums[k] - sums[i] < lower) ++k; + while (j < end && sums[j] - sums[i] <= upper) ++j; + while (t < end && sums[t] < sums[i]) cache[r++] = sums[t++]; + cache[r] = sums[i]; + cnt += j - k; + } + for (int i = 0; i < t-start; ++i) sums[start+i] = cache[i]; + return cnt; + } + } + + public class UnitTest { + + + } +} diff --git a/src/main/java/count_primes/CountPrimes.java b/src/main/java/count_primes/CountPrimes.java new file mode 100644 index 0000000..dd10573 --- /dev/null +++ b/src/main/java/count_primes/CountPrimes.java @@ -0,0 +1,35 @@ +package count_primes; + +public class CountPrimes { + + public class Solution { + public int countPrimes(int n) { + if (n < 3) { + return 0; + } + boolean[] a = new boolean[n]; + a[0] = true; + a[1] = true; + int i = 2; + while (i * i < n) { + if (!a[i]) { + int j = i * i; + while (j < n) { + a[j] = true; + j += i; + } + } + i++; + } + int count = 0; + for (boolean _a : a) { + if (!_a) { + count++; + } + } + return count; + } + } + +} + diff --git a/src/main/java/count_univalue_subtrees/CountUnivalueSubtrees.java b/src/main/java/count_univalue_subtrees/CountUnivalueSubtrees.java new file mode 100644 index 0000000..0343aa3 --- /dev/null +++ b/src/main/java/count_univalue_subtrees/CountUnivalueSubtrees.java @@ -0,0 +1,43 @@ +package count_univalue_subtrees; + +import common.TreeNode; + +/** + * Created by lxie on 5/23/18. + */ +public class CountUnivalueSubtrees { + + public static class Solution { + + public int countUnivalSubtrees (TreeNode root) { + int[] res = new int[1]; + isUnival(root, -1, res); + return res[0]; + } + + private boolean isUnival(TreeNode root, int val, int[] res) { + if (root == null) return true; + if (!isUnival(root.left, root.val, res) | !isUnival(root.right, root.val, res)) { + return false; + } + ++res[0]; + return root.val == val; + } + + } + + public static void main(String[] args) { + Solution sol = new Solution(); + + TreeNode root = new TreeNode(5); + root.left = new TreeNode(1); root.right = new TreeNode(5); + root.left.left = new TreeNode(5); root.left.right = new TreeNode(5); + root.right.right = new TreeNode(5); + + int res = sol.countUnivalSubtrees(root); + + System.out.println("result is " + res); + } + + +} diff --git a/src/main/java/course_schedule/CourseSchedule.java b/src/main/java/course_schedule/CourseSchedule.java new file mode 100644 index 0000000..8eb9346 --- /dev/null +++ b/src/main/java/course_schedule/CourseSchedule.java @@ -0,0 +1,47 @@ +package course_schedule; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +public class CourseSchedule { + + public class Solution { + public boolean canFinish(int numCourses, int[][] prerequisites) { + Map> outNodes = new HashMap>(); + int[] inDegree = new int[numCourses]; + Set courses = new HashSet(numCourses); + for (int i = 0; i < numCourses; i++) { + courses.add(i); + outNodes.put(i, new ArrayList()); + } + for (int[] edge : prerequisites) { + int from = edge[1]; + int to = edge[0]; + inDegree[to]++; + outNodes.get(from).add(to); + } + while (!courses.isEmpty()) { + List toRemoved = new ArrayList(); + for (int course : courses) { + if (inDegree[course] == 0) { + toRemoved.add(course); + for (int node : outNodes.get(course)) { + inDegree[node]--; + } + } + } + if (toRemoved.isEmpty()) { + return false; + } + courses.removeAll(toRemoved); + } + return true; + } + } + +} + diff --git a/src/main/java/course_schedule_ii/CourseScheduleII.java b/src/main/java/course_schedule_ii/CourseScheduleII.java new file mode 100644 index 0000000..6d134ad --- /dev/null +++ b/src/main/java/course_schedule_ii/CourseScheduleII.java @@ -0,0 +1,50 @@ +package course_schedule_ii; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; +import java.util.Queue; + +/** + * Created by lxie on 2/6/18. + */ +public class CourseScheduleII { + + public class Solution { + public int[] findOrder(int numCourses, int[][] prerequisites) { + List res = new ArrayList<>(); + List> graph = new ArrayList<>(); + for (int i=0; i()); + int[] in = new int[numCourses]; + for (int[] a : prerequisites) { + graph.get(a[1]).add(a[0]); + ++in[a[0]]; + } + Queue q = new LinkedList<>(); + for (int i = 0; i < numCourses; ++i) { + if (in[i] == 0) q.add(i); + } + while (q.isEmpty() == false) { + int t = q.peek(); + res.add(t); // get result + q.poll(); + for (int a : graph.get(t)) { + --in[a]; + if (in[a] == 0) q.add(a); + } + } + if (res.size() != numCourses) res.clear(); // clear if cannot finish + return res.stream().mapToInt(i->i).toArray(); + + } + + } + + public static class UnitTest { + + + + } + +} diff --git a/src/main/java/create_max_number/CreateMaxNumber.java b/src/main/java/create_max_number/CreateMaxNumber.java new file mode 100644 index 0000000..2775616 --- /dev/null +++ b/src/main/java/create_max_number/CreateMaxNumber.java @@ -0,0 +1,80 @@ +package create_max_number; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * Created by lxie on 9/5/18. + */ +public class CreateMaxNumber { + + public static class Solution { + + public int[] maxNumber(int[] nums1, int[] nums2, int k) { + int m = nums1.length, n = nums2.length; + int[] res = {}; + for (int i = Math.max(0, k - n); i <= Math.min(k, m); ++i) { + // constraint: k-i <= n, i <=m, i = [0, k] + int[] merged = mergeVector(maxVector(nums1, i), maxVector(nums2, k - i)); + res = maxArray(res, merged) == 0 ? res : merged; + } + return res; + } + + private int[] maxVector(int[] nums, int k) { + int drop = nums.length - k; + List res = new ArrayList<>(); + for (int num : nums) { + while (drop != 0 && res.size() != 0 && res.get(res.size()-1) < num) { + res.remove(res.size()-1); + --drop; + } + res.add(num); + } + res = res.subList(0, k); + return res.stream().mapToInt(i->i).toArray(); + } + + private int[] mergeVector(int[] nums1, int[] nums2) { // just a merge sort + List res = new ArrayList<>(); + int i = 0, j = 0; + while (i < nums1.length && j < nums2.length) { + if (maxArray(Arrays.copyOfRange(nums1, i, nums1.length), + Arrays.copyOfRange(nums2, j, nums2.length)) == 0) { + res.add(nums1[i++]); + } else { + res.add(nums2[j++]); + } + } + + if (i < nums1.length) { + for (int k = i; k < nums1.length; ++k) res.add(nums1[k]); + } else { + for (int k = j; k < nums2.length; ++k) res.add(nums2[k]); + } + + return res.stream().mapToInt(m->m).toArray(); + } + + private int maxArray(int[] a, int[] b) { + int i = 0, j = 0; + while (i < a.length && j < b.length) { + if (a[i] > b[j]) return 0; + else if(a[i] < b[j]) return 1; + i++; j++; + } + if(i == a.length) return 1; + else return 0; + } + } + + public static void main(String[] args) { + Solution sol = new Solution(); + int[] a = {6,7}; + int[] b = {6,0,4}; + int[] res = sol.maxNumber(a, b, 5); + System.out.println(res); + } + +} diff --git a/src/main/java/daily_temperature/DailyTemperature.java b/src/main/java/daily_temperature/DailyTemperature.java new file mode 100644 index 0000000..5894281 --- /dev/null +++ b/src/main/java/daily_temperature/DailyTemperature.java @@ -0,0 +1,31 @@ +package daily_temperature; + +import java.util.Stack; + +/** + * Created by lxie on 7/24/18. + */ +public class DailyTemperature { + + public class Solution { + + public int[] dailyTemperatures(int[] temperatures) { + int n = temperatures.length; + int[] res = new int[n]; + Stack st = new Stack<>(); + for (int i = 0; i < temperatures.length; ++i) { + while (!st.empty() && temperatures[i] > temperatures[st.peek()]) { + int t = st.peek(); st.pop(); + res[t] = i - t; + } + st.push(i); + } + return res; + } + + } + + public class UnitTest { + + } +} diff --git a/src/main/java/decode_string/DecodeString.java b/src/main/java/decode_string/DecodeString.java new file mode 100644 index 0000000..bd64da0 --- /dev/null +++ b/src/main/java/decode_string/DecodeString.java @@ -0,0 +1,43 @@ +package decode_string; + +/** + * Created by lxie on 8/19/18. + */ +public class DecodeString { + + public class Solution { + public String decodeString(String s) { + int[] i = {0}; + return decode(s, i); + } + + private String decode(String s, int[] i) { + String res = ""; + int n = s.length(); + while (i[0] < n && s.charAt(i[0]) != ']') { + if (s.charAt(i[0]) < '0' || s.charAt(i[0]) > '9') { + res += s.charAt(i[0]++); + } else { + int cnt = 0; + while (i[0] < n && s.charAt(i[0]) >= '0' && + s.charAt(i[0]) <= '9') { + cnt = cnt * 10 + s.charAt(i[0]++) - '0'; + } + ++i[0]; // skip '[' + String t = decode(s, i); + ++i[0]; // skip ']' and continue + while (cnt-- > 0) { + res += t; + } + } + } + return res; + } + + } + + public class UnitTest { + + + } +} diff --git a/src/main/java/decode_ways_ii/DecodeWaysII.java b/src/main/java/decode_ways_ii/DecodeWaysII.java new file mode 100644 index 0000000..3ae8f7b --- /dev/null +++ b/src/main/java/decode_ways_ii/DecodeWaysII.java @@ -0,0 +1,35 @@ +package decode_ways_ii; + +/** + * Created by lxie on 9/29/18. + */ +public class DecodeWaysII { + + public class Solution { + + public int numDecodings(String s) { + long e0 = 1, e1 = 0, e2 = 0, f0 = 0; + double M = 1e9 + 7; + for (char c : s.toCharArray()) { + if (c == '*') { + f0 = 9 * e0 + 9 * e1 + 6 * e2; + e1 = e0; + e2 = e0; + } else { + f0 = (c > '0'? 1 : 0) * e0 + e1 + (c <= '6'? 1 : 0) * e2; + e1 = (c == '1'? 1 : 0) * e0; + e2 = (c == '2'? 1: 0) * e0; + } + e0 = f0 % (long)M; + } + return (int) e0; + } + } + + public class UnitTest { + + + } + + +} diff --git a/src/main/java/delete_node_in_bst/DeleteNodeInBst.java b/src/main/java/delete_node_in_bst/DeleteNodeInBst.java new file mode 100644 index 0000000..909d6d7 --- /dev/null +++ b/src/main/java/delete_node_in_bst/DeleteNodeInBst.java @@ -0,0 +1,35 @@ +package delete_node_in_bst; + +import common.TreeNode; + +/** + * Created by lxie on 8/17/18. + */ +public class DeleteNodeInBst { + + public class Solution { + public TreeNode deleteNode(TreeNode root, int key) { + if (root == null) return null; + if (root.val > key) { + root.left = deleteNode(root.left, key); + } else if (root.val < key) { + root.right = deleteNode(root.right, key); + } else { + if (root.left == null || root.right == null) { + root = (root.left != null) ? root.left : root.right; + } else { + TreeNode cur = root.right; + while (cur.left != null) cur = cur.left; + root.val = cur.val; + root.right = deleteNode(root.right, cur.val); + } + } + return root; + } + } + + public class UnitTest { + + } + +} diff --git a/src/main/java/delete_ops_two_strings/DeleteOpsTwoStrings.java b/src/main/java/delete_ops_two_strings/DeleteOpsTwoStrings.java new file mode 100644 index 0000000..e0b7147 --- /dev/null +++ b/src/main/java/delete_ops_two_strings/DeleteOpsTwoStrings.java @@ -0,0 +1,33 @@ +package delete_ops_two_strings; + +/** + * Created by lxie on 9/13/18. + */ +public class DeleteOpsTwoStrings { + + public class Solution { + + public int minDistance(String word1, String word2) { + int n1 = word1.length(), n2 = word2.length(); + int[][] dp = new int[n1+1][n2+1]; + for (int i = 0; i <= n1; ++i) dp[i][0] = i; + for (int j = 0; j <= n2; ++j) dp[0][j] = j; + for (int i = 1; i <= n1; ++i) { + for (int j = 1; j <= n2; ++j) { + if (word1.charAt(i - 1) == word2.charAt(j - 1)) { + dp[i][j] = dp[i - 1][j - 1]; + } else { + dp[i][j] = 1 + Math.min(dp[i - 1][j], dp[i][j - 1]); + } + } + } + return dp[n1][n2]; + } + } + + public class UnitTest { + + } + + +} diff --git a/src/main/java/design_hit_counter/HitCounter.java b/src/main/java/design_hit_counter/HitCounter.java new file mode 100644 index 0000000..45e299a --- /dev/null +++ b/src/main/java/design_hit_counter/HitCounter.java @@ -0,0 +1,30 @@ +package design_hit_counter; + +import java.util.LinkedList; +import java.util.Queue; + +/** + * Created by lxie on 7/24/18. + */ +public class HitCounter { + + private Queue q = new LinkedList<>(); + + public HitCounter() {}; + + /** Record a hit. + @param timestamp - The current timestamp (in seconds granularity). */ + public void hit(int timestamp) { + q.add(timestamp); + } + + /** Return the number of hits in the past 5 minutes. + @param timestamp - The current timestamp (in seconds granularity). */ + public int getHits(int timestamp) { + while (q.isEmpty() && timestamp - q.peek() >= 300) { + q.poll(); + } + return q.size(); + } + +} diff --git a/src/main/java/design_phone_directory/PhoneDirectory.java b/src/main/java/design_phone_directory/PhoneDirectory.java new file mode 100644 index 0000000..c7ba652 --- /dev/null +++ b/src/main/java/design_phone_directory/PhoneDirectory.java @@ -0,0 +1,67 @@ +package design_phone_directory; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by lxie on 9/22/17. + */ +public class PhoneDirectory { + + private int max_num, next, idx; + private List recycle = new ArrayList<>(); + private List flag = new ArrayList<>(); + + /** Initialize your data structure here + @param maxNumbers - The maximum numbers that can be stored in the phone directory. */ + public PhoneDirectory(int maxNumbers) { + max_num = maxNumbers; + next = idx = 0; + for (int i=0; i 0) { + int t = recycle.get(--idx); + flag.set(t, false); + return t; + } + flag.set(next, false); + return next++; + } + + /** Check if a number is available or not. */ + public boolean check(int number) { + return number >= 0 && number < max_num && flag.get(number); + } + + /** Recycle or release a number. */ + public void release(int number) { + if (number >= 0 && number < max_num && !flag.get(number)) { + recycle.add(number); + idx++; + flag.set(number, true); + } + } + + + + public static void main(String[] args) { + System.out.println("this is for test"); + PhoneDirectory phones = new PhoneDirectory(3); + System.out.println("directory.get() ->" + phones.get()); + System.out.println("directory.get() ->" + phones.get()); + System.out.println("directory.check(2) ->" + phones.check(2)); + System.out.println("directory.get() ->" + phones.get()); + System.out.println("directory.check(2) ->" + phones.check(2)); + System.out.println("directory.release(2) ->"); + phones.release(2); + System.out.println("directory.check(2) ->" + phones.check(2)); + } + +} diff --git a/src/main/java/design_search_autocomplete_system/SearchAutoComplete.java b/src/main/java/design_search_autocomplete_system/SearchAutoComplete.java new file mode 100644 index 0000000..01ff3ec --- /dev/null +++ b/src/main/java/design_search_autocomplete_system/SearchAutoComplete.java @@ -0,0 +1,64 @@ +package design_search_autocomplete_system; + +import common.Pair; + +import java.util.*; + +/** + * Created by lxie on 9/1/18. + */ +public class SearchAutoComplete { + + public Map freq = new HashMap<>(); + public String data = null; + + public void SearchAutoComplete(String[] sentences, int[] times) { + for (int i = 0; i < sentences.length; ++i) { + if (freq.containsKey(sentences[i])) + freq.put(sentences[i], freq.get(sentences[i])+times[i]); + else + freq.put(sentences[i], times[i]); + } + data = ""; + } + + public List input(char c) { + if (c == '#') { + if (freq.containsKey(data)) + freq.put(data, freq.get(data)+1); + else + freq.put(data, 1); + data = ""; + return null; + } + data += c; + PriorityQueue> q = new PriorityQueue<>(50, new Comparator>() { + @Override + public int compare(Map.Entry o1, Map.Entry o2) { + if (o1.getValue() != o2.getValue()) + return o2.getValue() - o1.getValue(); // max heap + else + return o1.getKey().compareTo(o2.getKey()); + }}); + + for (Map.Entry f : freq.entrySet()) { + boolean matched = true; + for (int i = 0; i < data.length(); ++i) { + if (data.toCharArray()[i] != f.getKey().toCharArray()[i]) { + matched = false; + break; + } + } + if (matched) { + q.add(Pair.of(f.getKey(), f.getValue())); + if (q.size() > 3) q.poll(); + } + } + List res = new ArrayList<>(); + for (int i = q.size() - 1; i >= 0; --i) { + res.add(q.peek().getKey()); q.poll(); + } + return res; + } + +} diff --git a/src/main/java/design_tic_tac_toe/DesignTicTacToe.java b/src/main/java/design_tic_tac_toe/DesignTicTacToe.java new file mode 100644 index 0000000..cf09c70 --- /dev/null +++ b/src/main/java/design_tic_tac_toe/DesignTicTacToe.java @@ -0,0 +1,39 @@ +package design_tic_tac_toe; + +import static java.lang.StrictMath.abs; + +/** + * Created by lxie on 1/24/18. + */ +public class DesignTicTacToe { + + public class Solution { + + public class TicTacToe { + private int N = 3; + private int[] rows = new int[N]; + private int[] cols = new int[N]; + private int diag = 0, rev_diag = 0; + + public void TicTacToe(int n) { + this.N = n; + } + + public int move(int row, int col, int player) { + int add = player == 1 ? 1 : -1; + rows[row] += add; cols[col] += add; + diag += (row == col ? add : 0); + rev_diag += (row == N - col - 1 ? add : 0); + return (abs(rows[row]) == N || abs(cols[col]) == N || abs(diag) == N + || abs(rev_diag) == N) ? player : 0; + } + + } + } + + + public static class UnitTest { + + } + +} diff --git a/src/main/java/diagonal_traverse/DiagonalTraverse.java b/src/main/java/diagonal_traverse/DiagonalTraverse.java new file mode 100644 index 0000000..ba59cd6 --- /dev/null +++ b/src/main/java/diagonal_traverse/DiagonalTraverse.java @@ -0,0 +1,31 @@ +package diagonal_traverse; + +/** + * Created by lxie on 8/28/18. + */ +public class DiagonalTraverse { + + public class Solution { + public int[] findDiagonalOrder(int[][] matrix) { + if (matrix.length == 0 || matrix[0].length == 0) return null; + int m = matrix.length, n = matrix[0].length, r = 0, c = 0, k = 0; + int[] res = new int[m*n]; + int[][] dirs = {{-1,1}, {1,-1}}; + for (int i = 0; i < m * n; ++i) { + res[i] = matrix[r][c]; + r += dirs[k][0]; + c += dirs[k][1]; + if (r >= m) {r = m - 1; c += 2; k = 1 - k;} + if (c >= n) {c = n - 1; r += 2; k = 1 - k;} + if (r < 0) {r = 0; k = 1 - k;} + if (c < 0) {c = 0; k = 1 - k;} + } + return res; + } + } + + public class UnitTest { + + } + +} diff --git a/src/main/java/diameter_of_binary_tree/DiameterBinaryTree.java b/src/main/java/diameter_of_binary_tree/DiameterBinaryTree.java new file mode 100644 index 0000000..abbdfb7 --- /dev/null +++ b/src/main/java/diameter_of_binary_tree/DiameterBinaryTree.java @@ -0,0 +1,37 @@ +package diameter_of_binary_tree; + +import common.TreeNode; + +import java.util.HashMap; +import java.util.Map; + +/** + * Created by lxie on 7/13/18. + */ +public class DiameterBinaryTree { + + public class Solution { + private Map m = new HashMap<>(); + + public int diameterOfBinaryTree(TreeNode root) { + int[] res = {0}; + maxDepth(root, res); + return res[0]; + } + int maxDepth(TreeNode node, int[] res) { + if (node == null) return 0; + if (m.containsKey(node)) return m.get(node); + int left = maxDepth(node.left, res); + int right = maxDepth(node.right, res); + res[0] = Math.max(res[0], left + right); + int ret = Math.max(left, right) + 1; + m.put(node, ret); + return ret; + } + } + + public class UnitTest { + + + } +} diff --git a/src/main/java/divide_two_integers/DivideTwoIntegers.java b/src/main/java/divide_two_integers/DivideTwoIntegers.java index 33e1982..4c6d1d2 100644 --- a/src/main/java/divide_two_integers/DivideTwoIntegers.java +++ b/src/main/java/divide_two_integers/DivideTwoIntegers.java @@ -1,52 +1,38 @@ package divide_two_integers; -import static org.junit.Assert.assertEquals; - import org.junit.Test; +import org.junit.experimental.runners.Enclosed; +import org.junit.runner.RunWith; +@RunWith(Enclosed.class) public class DivideTwoIntegers { public class Solution { - // Try to implement without long public int divide(int dividend, int divisor) { - if (divisor == 0) { - throw new IllegalArgumentException("divisor is 0"); - } - if (divisor == Integer.MIN_VALUE) { - return dividend == Integer.MIN_VALUE ? 1 : 0; - } - boolean negative = (dividend > 0) ^ (divisor > 0); - divisor = Math.abs(divisor); - boolean overflow = dividend == Integer.MIN_VALUE; - if (overflow) { - dividend += divisor; - } - dividend = Math.abs(dividend); - int pow = divisor; - while ((pow << 1) > 0 && dividend >= (pow << 1)) { - pow <<= 1; - } - int ans = 0; - while (pow >= divisor) { - ans <<= 1; - if (dividend >= pow) { - dividend -= pow; - ans += 1; + long m = Math.abs((long)dividend), n = Math.abs((long)divisor), res = 0; + if (m < n) return 0; + while (m >= n) { + long t = n, p = 1; + while (m > (t << 1)) { + t <<= 1; + p <<= 1; + } + res += p; + m -= t; } - pow >>= 1; + if ((dividend < 0) ^ (divisor < 0)) res = -res; + return (int) (res > Integer.MAX_VALUE ? Integer.MAX_VALUE : res); // -INT_MIN could be invalid } - if (overflow) { - ans += 1; - } - return negative ? -ans : ans; + } - } public static class UnitTest { @Test public void testDivideWithOverflow() { Solution s = new DivideTwoIntegers().new Solution(); - assertEquals(Integer.MIN_VALUE, s.divide(Integer.MIN_VALUE, 1)); + System.out.println(s.divide(-2147483648, -1)); + + //assertEquals(Integer.MIN_VALUE, s.divide(Integer.MIN_VALUE, 1)); } } } diff --git a/src/main/java/dungeon_game/DungeonGame.java b/src/main/java/dungeon_game/DungeonGame.java new file mode 100644 index 0000000..c50a7c5 --- /dev/null +++ b/src/main/java/dungeon_game/DungeonGame.java @@ -0,0 +1,32 @@ +package dungeon_game; + + +public class DungeonGame { + + public class Solution { + public int calculateMinimumHP(int[][] dungeon) { + int m = dungeon.length; + int n = dungeon[0].length; + int[][] dp = new int[m][n]; + dp[m - 1][n - 1] = Math.max(1, 1 - dungeon[m - 1][n - 1]); + for (int i = m - 2; i >= 0; --i) { + dp[i][n - 1] = Math.max(1, dp[i + 1][n - 1] - dungeon[i][n - 1]); + } + for (int j = n - 2; j >= 0; --j) { + dp[m - 1][j] = Math.max(1, dp[m - 1][j + 1] - dungeon[m - 1][j]); + } + for (int i = m - 2; i >= 0; --i) { + for (int j = n - 2; j >= 0; --j) { + dp[i][j] = Math.max(1, Math.min(dp[i + 1][j], dp[i][j + 1]) - dungeon[i][j]); + } + } + return dp[0][0]; + + } + } + + public static class UnitTest { + + } +} + diff --git a/src/main/java/edit_distance/EditDistance.java b/src/main/java/edit_distance/EditDistance.java index c860709..e060e1c 100644 --- a/src/main/java/edit_distance/EditDistance.java +++ b/src/main/java/edit_distance/EditDistance.java @@ -4,23 +4,20 @@ public class EditDistance { public class Solution { public int minDistance(String word1, String word2) { - assert word1 != null && word2 != null; - int[][] dp = new int[word1.length() + 1][word2.length() + 1]; - for (int i = 0; i <= word2.length(); i++) { - dp[0][i] = i; - } - for (int i = 1; i <= word1.length(); i++) { - dp[i][0] = i; - for (int j = 1; j <= word2.length(); j++) { - dp[i][j] = Math.min(dp[i - 1][j], dp[i][j - 1]) + 1; - if (word1.charAt(i - 1) == word2.charAt(j - 1)) { - dp[i][j] = Math.min(dp[i][j], dp[i - 1][j - 1]); + int n1 = word1.length(), n2 = word2.length(); + int[][] dp = new int[n1 + 1][n2 + 1]; + for (int i = 0; i <= n1; ++i) dp[i][0] = i; + for (int i = 0; i <= n2; ++i) dp[0][i] = i; + for (int i = 1; i <= n1; ++i) { + for (int j = 1; j <= n2; ++j) { + if (word1.charAt(i-1) == word2.charAt(j - 1)) { + dp[i][j] = dp[i - 1][j - 1]; } else { - dp[i][j] = Math.min(dp[i][j], dp[i - 1][j - 1] + 1); + dp[i][j] = Math.min(dp[i - 1][j - 1], Math.min(dp[i - 1][j], dp[i][j - 1])) + 1; } } } - return dp[word1.length()][word2.length()]; + return dp[n1][n2]; } } diff --git a/src/main/java/employee_importance/EmployeeImportance.java b/src/main/java/employee_importance/EmployeeImportance.java new file mode 100644 index 0000000..e20425c --- /dev/null +++ b/src/main/java/employee_importance/EmployeeImportance.java @@ -0,0 +1,49 @@ +package employee_importance; + +import java.util.*; + +/** + * Created by lxie on 8/18/18. + */ + + +// Employee info +class Employee { + // It's the unique id of each node; + // unique id of this employee + public int id; + // the importance value of this employee + public int importance; + // the id of direct subordinates + public List subordinates; +}; + + +public class EmployeeImportance { + + public class Solution { + public int getImportance(List employees, int id) { + Set s = new HashSet<>(); + Map m = new HashMap<>(); + for (Employee e : employees) + m.put(e.id, e); // fast find + return helper(id, m, s); + } + + private int helper(int id, Map m, Set s) { + if (s.contains(id)) return 0; + s.add(id); + int res = m.get(id).importance; + for (int num : m.get(id).subordinates) { + res += helper(num, m, s); + } + return res; + } + } + + public class UnitTest { + + + } + +} diff --git a/src/main/java/encode_decode_strings/EncodeDecodeStrings.java b/src/main/java/encode_decode_strings/EncodeDecodeStrings.java new file mode 100644 index 0000000..ec97332 --- /dev/null +++ b/src/main/java/encode_decode_strings/EncodeDecodeStrings.java @@ -0,0 +1,50 @@ +package encode_decode_strings; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * Created by lxie on 6/12/18. + */ +public class EncodeDecodeStrings { + + public static class Solution { + + // Encodes a list of strings to a single string. + public String encode(List strs) { + String res = ""; + for (String a : strs) { + res += Integer.toString(a.length()) + "/" + a; + } + return res; + } + // Decodes a single string to a list of strings. + public List decode(String s) { + List res = new ArrayList<>(); + int i = 0; + while (i < s.length()) { + int found = s.indexOf("/", i); + int len = Integer.parseInt(s.substring(i, found)); + res.add(s.substring(found + 1, found + len + 1)); + i = found + len + 1; + } + return res; + } + + + + } + + public static void main(String[] args) { + System.out.println("this is for test"); + Solution sol = new Solution(); + + String encoded = sol.encode(new ArrayList<>(Arrays.asList("a", "ab", "abc"))); + System.out.println("encode = " + encoded); + + List decoded = sol.decode(encoded); + System.out.println(decoded.toString()); + } + +} diff --git a/src/main/java/encode_decode_tinyurl/EncodeDecodeTinyUrl.java b/src/main/java/encode_decode_tinyurl/EncodeDecodeTinyUrl.java new file mode 100644 index 0000000..6209c21 --- /dev/null +++ b/src/main/java/encode_decode_tinyurl/EncodeDecodeTinyUrl.java @@ -0,0 +1,47 @@ +package encode_decode_tinyurl; + +import java.util.HashMap; +import java.util.Map; +import java.util.Random; + +/** + * Created by lxie on 7/21/18. + */ +public class EncodeDecodeTinyUrl { + + private Map short2long = new HashMap<>(); + private Map long2short = new HashMap<>(); + private String dict = ""; + + public EncodeDecodeTinyUrl(String longUrl) { + dict = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; + } + + // Encodes a URL to a shortened URL. + public String encode(String longUrl) { + if (long2short.containsKey(longUrl)) { + return "http://tinyurl.com/" + long2short.get(longUrl); + } + int idx = 0; + String randStr = ""; + for (int i = 0; i < 6; ++i) { + Random rand = new Random(); + randStr += dict.charAt(rand.nextInt() % 62); + } + while (short2long.containsKey(randStr)) { + Random rand = new Random(); + randStr.toCharArray()[idx] = dict.charAt(rand.nextInt() % 62); + idx = (idx + 1) % 5; + } + short2long.put(randStr, longUrl); + long2short.put(longUrl, randStr); + return "http://tinyurl.com/" + randStr; + } + + // Decodes a shortened URL to its original URL. + public String decode(String shortUrl) { + String randStr = shortUrl.substring(shortUrl.lastIndexOf("/") + 1); + return short2long.containsKey(randStr) ? short2long.get(randStr) : shortUrl; + } + +} diff --git a/src/main/java/encode_string_shortest_lengh/EncodeStringShortestLength.java b/src/main/java/encode_string_shortest_lengh/EncodeStringShortestLength.java new file mode 100644 index 0000000..f3eef2c --- /dev/null +++ b/src/main/java/encode_string_shortest_lengh/EncodeStringShortestLength.java @@ -0,0 +1,40 @@ +package encode_string_shortest_lengh; + +/** + * Created by lxie on 8/25/18. + */ +public class EncodeStringShortestLength { + + public static class Solution { + + public String encode(String s) { + int n = s.length(); + String[][] dp = new String[n][n]; + for (int step = 1; step <= n; ++step) { + for (int i = 0; i + step - 1 < n; ++i) { + int j = i + step - 1; + dp[i][j] = s.substring(i, i+step); + for (int k = i; k < j; ++k) { + String left = dp[i][k], right = dp[k + 1][j]; + if (left.length() + right.length() < dp[i][j].length()) { + dp[i][j] = left + right; + } + } + String t = s.substring(i, j+1), replace = ""; + int pos = (t + t).indexOf(t, 1); + if (pos >= t.length()) replace = t; + else replace = Integer.toString(t.length() / pos) + '[' + dp[i][i + pos - 1] + ']'; + if (replace.length() < dp[i][j].length()) dp[i][j] = replace; + } + } + return dp[0][n - 1]; + } + + } + + public static void main(String[] args) { + Solution sol = new Solution(); + System.out.println(sol.encode("abbbabbbcabbbabbbc")); + + } +} diff --git a/src/main/java/evaluate_division/EvaluateDivision.java b/src/main/java/evaluate_division/EvaluateDivision.java new file mode 100644 index 0000000..dd3775e --- /dev/null +++ b/src/main/java/evaluate_division/EvaluateDivision.java @@ -0,0 +1,69 @@ +package evaluate_division; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +/** + * Created by lxie on 8/22/18. + */ +public class EvaluateDivision { + + public static class Solution { + + public double[] calcEquation(String[][] equations, double[] values, String[][] queries) { + double[] res = new double[queries.length]; + for (int i=0; i s = new HashSet<>(); + for (String[] a : equations) { + s.add(a[0]); + s.add(a[1]); + } + for (int i = 0; i < queries.length; ++i) { + String[] query = queries[i]; + if (s.contains(query[0]) && s.contains(query[1])) { + List v = new ArrayList<>(); // visited exprs + res[i] = helper(equations, values, query, v); + } + } + return res; + } + + private double helper(String[][] equations, double[] values, String[] query, List v) { + for (int i = 0; i < equations.length; ++i) { + if (equations[i][0] == query[0] && equations[i][1] == query[1]) return values[i]; + if (equations[i][0] == query[1] && equations[i][1] == query[0]) return 1.0 / values[i]; + } + for (int i = 0; i < equations.length; ++i) { + if (!v.contains(i) && equations[i][0] == query[0]) { // case 1, 2 + v.add(i); // visited + String[] expr = {equations[i][1], query[1]}; + double t = values[i] * helper(equations, values, expr, v); + if (t > 0) return t; + else v.remove(v.size()-1); + } + if (!v.contains(i) && equations[i][1] == query[0]) { // case 3 + v.add(i); + String[] expr = {equations[i][0], query[1]}; + double t = helper(equations, values, expr, v) / values[i]; + if (t > 0) return t; + else v.remove(v.size()-1); + } + } + return -1.0; + } + + + } + + public static void main(String[] args) { + Solution sol = new Solution(); + String[][] equations = {{"a", "b"}, {"b", "c"}}; + double[] values = {2.0, 3.0}; + String[][] queries = {{"a", "c"}, {"b", "c"}, {"a", "e"}, {"a", "a"}, {"x", "x"}}; + double[] res = sol.calcEquation(equations, values, queries); + System.out.println(res.toString()); + } + +} diff --git a/src/main/java/evaluate_reverse_polish_notation/EvaluateReversePolishNotation.java b/src/main/java/evaluate_reverse_polish_notation/EvaluateReversePolishNotation.java new file mode 100644 index 0000000..5c21723 --- /dev/null +++ b/src/main/java/evaluate_reverse_polish_notation/EvaluateReversePolishNotation.java @@ -0,0 +1,38 @@ +package evaluate_reverse_polish_notation; + +import java.util.ArrayDeque; + +public class EvaluateReversePolishNotation { + + public class Solution { + public int evalRPN(String[] tokens) { + ArrayDeque stack = new ArrayDeque(); + for (String token : tokens) { + if (token.equals("+")) { + int num2 = stack.removeLast(); + int num1 = stack.removeLast(); + stack.offerLast(num1 + num2); + } else if (token.equals("-")) { + int num2 = stack.removeLast(); + int num1 = stack.removeLast(); + stack.offerLast(num1 - num2); + } else if (token.equals("*")) { + int num2 = stack.removeLast(); + int num1 = stack.removeLast(); + stack.offerLast(num1 * num2); + } else if (token.equals("/")) { + int num2 = stack.removeLast(); + int num1 = stack.removeLast(); + stack.offerLast(num1 / num2); + } else { + stack.offerLast(Integer.parseInt(token)); + } + } + return stack.removeLast(); + } + } + + public static class UnitTest { + + } +} diff --git a/src/main/java/excel_sheet_column_number/ExcelSheetColumnNumber.java b/src/main/java/excel_sheet_column_number/ExcelSheetColumnNumber.java new file mode 100644 index 0000000..d606d2e --- /dev/null +++ b/src/main/java/excel_sheet_column_number/ExcelSheetColumnNumber.java @@ -0,0 +1,20 @@ +package excel_sheet_column_number; + +public class ExcelSheetColumnNumber { + + public class Solution { + public int titleToNumber(String s) { + int n = 0; + for (int i = 0; i < s.length(); i++) { + char c = s.charAt(i); + n = n * 26 + c - 'A' + 1; + } + return n; + } + } + + public static class UnitTest { + + } +} + diff --git a/src/main/java/excel_sheet_column_title/ExcelSheetColumnTitle.java b/src/main/java/excel_sheet_column_title/ExcelSheetColumnTitle.java new file mode 100644 index 0000000..a622509 --- /dev/null +++ b/src/main/java/excel_sheet_column_title/ExcelSheetColumnTitle.java @@ -0,0 +1,22 @@ +package excel_sheet_column_title; + +public class ExcelSheetColumnTitle { + + public class Solution { + public String convertToTitle(int n) { + StringBuilder builder = new StringBuilder(); + while (n != 0) { + n--; + char c = (char) (n % 26 + 'A'); + builder.append(c); + n /= 26; + } + return builder.reverse().toString(); + } + } + + public static class UnitTest { + + } +} + diff --git a/src/main/java/exclusive_time_of_functions/ExclusiveTimeOfFunctions.java b/src/main/java/exclusive_time_of_functions/ExclusiveTimeOfFunctions.java new file mode 100644 index 0000000..37ab9fd --- /dev/null +++ b/src/main/java/exclusive_time_of_functions/ExclusiveTimeOfFunctions.java @@ -0,0 +1,45 @@ +package exclusive_time_of_functions; + +import java.util.List; +import java.util.Stack; + +/** + * Created by lxie on 9/26/18. + */ +public class ExclusiveTimeOfFunctions { + + public class Solution { + + public int[] exclusiveTime(int n, List logs) { + int[] res = new int[n]; + Stack st = new Stack<>(); + int preTime = 0; + for (String log : logs) { + String[] params = log.split(":"); + int idx = Integer.parseInt(params[0]); + String type = params[1]; + int time = Integer.parseInt(params[2]); + if (!st.empty()) { + res[st.peek()] += time - preTime; + } + preTime = time; + if (type.equals("start")) st.push(idx); + else { + int t = st.peek(); st.pop(); + ++res[t]; // add 1s for ended task + ++preTime; + } + } + return res; + } + + } + + public class UnitTest { + + + + } + + +} diff --git a/src/main/java/expr_add_ops/ExprAddOps.java b/src/main/java/expr_add_ops/ExprAddOps.java new file mode 100644 index 0000000..857477a --- /dev/null +++ b/src/main/java/expr_add_ops/ExprAddOps.java @@ -0,0 +1,48 @@ +package expr_add_ops; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by lxie on 6/15/18. + */ +public class ExprAddOps { + + public static class Solution { + + public List addOperators(String num, int target) { + List res = new ArrayList<>(); + addOperatorsDFS(num, target, 0, 0, "", res); + return res; + } + + public void addOperatorsDFS(String num, int target, long diff, long curNum, String out, List res) { + if (num.length() == 0 && curNum == target) { + res.add(out); + } + for (int i = 1; i <= num.length(); ++i) { + String cur = num.substring(0, i); + if (cur.length() > 1 && cur.charAt(0) == '0') return; + String next = num.substring(i); + Long curLong = Long.parseLong(cur); + if (out.length() > 0) { + addOperatorsDFS(next, target, curLong, curNum + curLong, out + "+" + cur, res); + addOperatorsDFS(next, target, -curLong, curNum - curLong, out + "-" + cur, res); + addOperatorsDFS(next, target, diff * curLong, (curNum - diff) + diff * curLong, out + "*" + cur, res); + } else { + addOperatorsDFS(next, target, curLong, curLong, cur, res); // first split + } + } + } + } + + public static void main(String[] args) { + System.out.println("this is for test"); + Solution sol = new Solution(); + + System.out.println(sol.addOperators("232", 8)); + + } + + +} diff --git a/src/main/java/factor_combinations/FactorCombinations.java b/src/main/java/factor_combinations/FactorCombinations.java new file mode 100644 index 0000000..7e9ec36 --- /dev/null +++ b/src/main/java/factor_combinations/FactorCombinations.java @@ -0,0 +1,40 @@ +package factor_combinations; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by lxie on 5/27/18. + */ +public class FactorCombinations { + + public static class Solution { + + public List> getFactors(int n) { + List> res = new ArrayList<>(); + helper(n, 2, new ArrayList(), res); + return res; + } + + void helper(int n, int start, List out, List> res) { + if (n == 1) { + if (out.size() > 1) res.add(new ArrayList<>(out)); + } else { + for (int i = start; i <= n; ++i) { + if (n % i == 0) { + out.add(i); + helper(n / i, i, out, res); + out.remove(out.size()-1); + } + } + } + } + + } + + public static void main(String[] args) { + Solution sol = new Solution(); + System.out.println("result is " + sol.getFactors(32)); + } + +} diff --git a/src/main/java/factorial_trailing_zeroes/FactorialTrailingZeroes.java b/src/main/java/factorial_trailing_zeroes/FactorialTrailingZeroes.java new file mode 100644 index 0000000..c785493 --- /dev/null +++ b/src/main/java/factorial_trailing_zeroes/FactorialTrailingZeroes.java @@ -0,0 +1,21 @@ +package factorial_trailing_zeroes; + +public class FactorialTrailingZeroes { + + public class Solution { + public int trailingZeroes(int n) { + int times = 5; + int zeroes = 0; + while (n >= times) { + zeroes += n / times; + times *= 5; + } + return zeroes; + } + } + + public static class UnitTest { + + } +} + diff --git a/src/main/java/find_anagram_mappings/FindAnagramMappings.java b/src/main/java/find_anagram_mappings/FindAnagramMappings.java new file mode 100644 index 0000000..7b749a8 --- /dev/null +++ b/src/main/java/find_anagram_mappings/FindAnagramMappings.java @@ -0,0 +1,32 @@ +package find_anagram_mappings; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Created by lxie on 7/4/18. + */ +public class FindAnagramMappings { + + public static class Solution { + + public List anagramMappings(int[] A, int[] B) { + List res = new ArrayList<>(); + Map m = new HashMap<>(); + for (int i = 0; i < B.length; ++i) { + m.put(B[i], i); + } + for (int num : A) res.add(m.get(num)); + return res; + } + } + + public static void main(String[] args) { + Solution sol = new Solution(); + int[] a = {12, 28, 46, 32, 50}; + int[] b = {50, 12, 32, 46, 28}; + System.out.println("result is " + sol.anagramMappings(a, b)); + } +} diff --git a/src/main/java/find_celebrity/FindCelebrity.java b/src/main/java/find_celebrity/FindCelebrity.java new file mode 100644 index 0000000..4764f70 --- /dev/null +++ b/src/main/java/find_celebrity/FindCelebrity.java @@ -0,0 +1,30 @@ +package find_celebrity; + +/** + * Created by lxie on 6/14/18. + */ +public class FindCelebrity { + + public class Solution { + + private boolean knows(int a, int b) { + // ... + return true; + } + + public int findCelebrity(int n) { + int res = 0; + for (int i = 0; i < n; ++i) { + if (knows(res, i)) res = i; // get a candidate + } + for (int i = 0; i < n; ++i) { + if (res != i && (knows(res, i) || !knows(i, res))) return -1; + } + return res; + } + } + + public class UnitTest { + + } +} diff --git a/src/main/java/find_disappeared_in_array/FindDisappearedInArray.java b/src/main/java/find_disappeared_in_array/FindDisappearedInArray.java new file mode 100644 index 0000000..7e5a548 --- /dev/null +++ b/src/main/java/find_disappeared_in_array/FindDisappearedInArray.java @@ -0,0 +1,41 @@ +package find_disappeared_in_array; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by lxie on 7/10/18. + */ +public class FindDisappearedInArray { + + public class Solution { + + public List findDisappearedNumbers(int[] nums) { + List res = new ArrayList<>(); + for (int i = 0; i < nums.length; ++i) { + if (nums[i] != nums[nums[i] - 1]) { + // swap in right order + int temp = nums[nums[i] - 1]; + nums[nums[i] - 1] = nums[i]; + nums[i] = temp; + + --i; + } + } + for (int i = 0; i < nums.length; ++i) { + if (nums[i] != i + 1) { + res.add(i + 1); + } + } + return res; + } + + } + + public class UnitTest { + + + + } + +} diff --git a/src/main/java/find_duplicate_number/FindDuplicateNumber.java b/src/main/java/find_duplicate_number/FindDuplicateNumber.java new file mode 100644 index 0000000..e8bf18d --- /dev/null +++ b/src/main/java/find_duplicate_number/FindDuplicateNumber.java @@ -0,0 +1,30 @@ +package find_duplicate_number; + +/** + * Created by lxie on 11/29/17. + */ +public class FindDuplicateNumber { + + public class Solution { + public int findDuplicate(int[] nums) { + int low = 1, high = nums.length - 1; // from 1 to n + while (low < high) { + int mid = low + (high - low) / 2; + int cnt = 0; + for (int a : nums) { + if (a <= mid) ++cnt; + } + if (cnt <= mid) low = mid + 1; + else high = mid; + } + return low; + + } + } + + public static class UnitTest { + + } + + +} diff --git a/src/main/java/find_duplicate_subtrees/FindDuplicateSubtrees.java b/src/main/java/find_duplicate_subtrees/FindDuplicateSubtrees.java new file mode 100644 index 0000000..12d90bc --- /dev/null +++ b/src/main/java/find_duplicate_subtrees/FindDuplicateSubtrees.java @@ -0,0 +1,38 @@ +package find_duplicate_subtrees; + +import common.TreeNode; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Created by lxie on 8/25/18. + */ +public class FindDuplicateSubtrees { + + public class Solution { + public List findDuplicateSubtrees(TreeNode root) { + List res = new ArrayList<>(); + Map m = new HashMap<>(); + helper(root, m, res); + return res; + } + + private String helper(TreeNode node, Map m, List res) { + if (node == null) return "#"; + String str = Integer.toString(node.val) + "," + helper(node.left, m, res) + "," + + helper(node.right, m, res); + if (m.containsKey(str) && m.get(str) == 1) res.add(node); + if (!m.containsKey(str)) m.put(str, 1); + else m.put(str, m.get(str)+1); + return str; + } + } + + public class UnitTest { + + } + +} diff --git a/src/main/java/find_k_closest_elements/FindKClosestElements.java b/src/main/java/find_k_closest_elements/FindKClosestElements.java new file mode 100644 index 0000000..5e8350e --- /dev/null +++ b/src/main/java/find_k_closest_elements/FindKClosestElements.java @@ -0,0 +1,32 @@ +package find_k_closest_elements; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by lxie on 9/20/18. + */ +public class FindKClosestElements { + + public class Solution { + + public List findClosestElements(int[] arr, int k, int x) { + int left = 0, right = arr.length - k; + List res = new ArrayList<>(); + while (left < right) { + int mid = left + (right - left) / 2; + if (x - arr[mid] > arr[mid + k] - x) left = mid + 1; + else right = mid; + } + for(int i = left; i<= left+k; ++i) res.add(arr[i]); + return res; + } + } + + public class UnitTest { + + + } + + +} diff --git a/src/main/java/find_k_pairs_smallest_sum/KPairsSmallestSum.java b/src/main/java/find_k_pairs_smallest_sum/KPairsSmallestSum.java new file mode 100644 index 0000000..3c868f5 --- /dev/null +++ b/src/main/java/find_k_pairs_smallest_sum/KPairsSmallestSum.java @@ -0,0 +1,48 @@ +package find_k_pairs_smallest_sum; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import java.util.PriorityQueue; + +/** + * Created by lxie on 1/27/18. + */ +public class KPairsSmallestSum { + + public class Solution { + + public List kSmallestPairs(int[] nums1, int[] nums2, int k) { + List res = new ArrayList<>(); + PairComparator comparator = new PairComparator(); + PriorityQueue q = new PriorityQueue<>(100, comparator); + for (int i = 0; i < Integer.min((int)nums1.length, k); ++i) { + for (int j = 0; j < Integer.min((int)nums2.length, k); ++j) { + if (q.size() < k) { + q.add(new int[] {nums1[i], nums2[j]}); + } else if (nums1[i] + nums2[j] < q.peek()[0] + q.peek()[1]) { + q.add(new int[]{nums1[i], nums2[j]}); q.poll(); + } + } + } + while (!q.isEmpty()) { + res.add(q.peek()); q.poll(); + } + return res; + } + + class PairComparator implements Comparator { + @Override + public int compare(int[] p1, int[] p2) { + return (p2[0] + p2[1]) - (p1[0] + p1[1]); + } + } + + } + + public static class UnitTest { + + + } + +} diff --git a/src/main/java/find_leaves_of_binary_tree/FindLeavesOfBinaryTree.java b/src/main/java/find_leaves_of_binary_tree/FindLeavesOfBinaryTree.java new file mode 100644 index 0000000..4600798 --- /dev/null +++ b/src/main/java/find_leaves_of_binary_tree/FindLeavesOfBinaryTree.java @@ -0,0 +1,42 @@ +package find_leaves_of_binary_tree; + +import java.util.ArrayList; +import common.TreeNode; + +/** + * Created by lxie on 9/9/17. + */ +public class FindLeavesOfBinaryTree { + + public static class Solution { + public ArrayList> findLeaves(TreeNode root){ + ArrayList> res = new ArrayList>(); + helper(root, res); + return res; + + } + + private int helper(TreeNode root, ArrayList> res) { + if(root == null) return -1; + int depth = 1 + Math.max(helper(root.left, res), helper(root.right, res)); + if (depth >= res.size()) res.add(new ArrayList<>()); + res.get(depth).add(root.val); + return depth; + } + + } + + public static void main(String[] args) { + System.out.println("this is for test"); + + Solution sol = new Solution(); + + TreeNode root = new TreeNode(10); + root.left = new TreeNode(5); root.right = new TreeNode(15); + root.left.left = new TreeNode(1); root.left.right = new TreeNode(8); + root.right.right = new TreeNode(7); + + ArrayList> result = sol.findLeaves(root); + System.out.print(result); + } +} diff --git a/src/main/java/find_median_in_stream/MedianInStream.java b/src/main/java/find_median_in_stream/MedianInStream.java new file mode 100644 index 0000000..be20da3 --- /dev/null +++ b/src/main/java/find_median_in_stream/MedianInStream.java @@ -0,0 +1,31 @@ +package find_median_in_stream; + +import java.util.Collections; +import java.util.PriorityQueue; + +/** + * Created by lxie on 6/20/18. + */ +public class MedianInStream { + + // by default min heap in java + private PriorityQueue small = new PriorityQueue(30, Collections.reverseOrder()); + private PriorityQueue large = new PriorityQueue(30); + + + public void addNum(int num) { + small.add(num); + large.add(small.peek()); + small.poll(); + if (small.size() < large.size()) { + small.add(large.peek()); + large.poll(); + } + } + + // Returns the median of current data stream + public double findMedian() { + return small.size() > large.size() ? (double) small.peek() : 0.5 *((int)small.peek() + (int)large.peek()); + } + +} diff --git a/src/main/java/find_minimum_in_rotated_sorted_array/FindMinimuminRotatedSortedArray.java b/src/main/java/find_minimum_in_rotated_sorted_array/FindMinimuminRotatedSortedArray.java new file mode 100644 index 0000000..c27dda1 --- /dev/null +++ b/src/main/java/find_minimum_in_rotated_sorted_array/FindMinimuminRotatedSortedArray.java @@ -0,0 +1,35 @@ +package find_minimum_in_rotated_sorted_array; + +import java.util.*; + +import org.junit.*; + +import static org.junit.Assert.*; + +public class FindMinimuminRotatedSortedArray { + + public class Solution { + public int findMin(int[] num) { + assert (num.length > 0); + int left = 0; + int right = num.length - 1; + while (left < right) { + if (num[left] < num[right]) { + return num[left]; + } + int mid = left + (right - left) / 2; + if (num[left] <= num[mid]) { + left = mid + 1; + } else { + right = mid; + } + } + return num[left]; + } + } + + public static class UnitTest { + + } +} + diff --git a/src/main/java/find_minimum_in_rotated_sorted_array_ii/FindMinimuminRotatedSortedArrayII.java b/src/main/java/find_minimum_in_rotated_sorted_array_ii/FindMinimuminRotatedSortedArrayII.java new file mode 100644 index 0000000..8223f79 --- /dev/null +++ b/src/main/java/find_minimum_in_rotated_sorted_array_ii/FindMinimuminRotatedSortedArrayII.java @@ -0,0 +1,40 @@ +package find_minimum_in_rotated_sorted_array_ii; + +import java.util.*; + +import org.junit.*; + +import static org.junit.Assert.*; + +public class FindMinimuminRotatedSortedArrayII { + + public class Solution { + public int findMin(int[] num) { + assert (num.length > 0); + int left = 0; + int right = num.length - 1; + while (left < right) { + if (num[left] < num[right]) { + return num[left]; + } else if (num[left] == num[right]) { + right--; + } else { + int mid = left + (right - left) / 2; + if (num[left] == num[mid]) { + left++; + } else if (num[left] < num[mid]) { + left = mid + 1; + } else { + right = mid; + } + } + } + return num[left]; + } + } + + public static class UnitTest { + + } +} + diff --git a/src/main/java/find_mode_bst/FindModeInBst.java b/src/main/java/find_mode_bst/FindModeInBst.java new file mode 100644 index 0000000..9b7948f --- /dev/null +++ b/src/main/java/find_mode_bst/FindModeInBst.java @@ -0,0 +1,50 @@ +package find_mode_bst; + +import common.TreeNode; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Created by lxie on 7/18/18. + */ +public class FindModeInBst { + + public class Solution { + + public List findMode(TreeNode root) { + List res = new ArrayList<>(); + int[] mx = {0}; + Map m = new HashMap<>(); + inorder(root, m, mx); + for (Map.Entry a : m.entrySet()) { + if (a.getValue().equals(mx)) { + res.add(a.getKey()); + } + } + return res; + } + + private void inorder(TreeNode node, Map m, int[] mx) { + if (node == null) return; + inorder(node.left, m, mx); + if (!m.containsKey(node.val)) { + m.put(node.val, 1); + } else { + m.put(node.val, m.get(node.val)+1); + } + mx[0] = Math.max(mx[0], m.get(node.val)); + inorder(node.right, m, mx); + } + + + } + + public class UnitTest { + + + } + +} diff --git a/src/main/java/find_mode_in_bst/FindModeInBST.java b/src/main/java/find_mode_in_bst/FindModeInBST.java new file mode 100644 index 0000000..d26b556 --- /dev/null +++ b/src/main/java/find_mode_in_bst/FindModeInBST.java @@ -0,0 +1,49 @@ +package find_mode_in_bst; + +import common.TreeNode; + +import java.util.ArrayList; +import java.util.List; +import java.util.Stack; + +/** + * Created by lxie on 9/1/18. + */ +public class FindModeInBST { + + public class Solution { + + public int[] findMode(TreeNode root) { + if (root == null) return new int[0]; + List res = new ArrayList<>(); + TreeNode p = root, pre = null; + Stack s = new Stack<>(); + int mx = 0, cnt = 1;; + while (!s.isEmpty() || p != null) { + while (p != null) { + s.push(p); + p = p.left; + } + p = s.peek(); s.pop(); + if (pre != null) { + cnt = (p.val == pre.val) ? cnt + 1 : 1; + } + if (cnt >= mx) { + if (cnt > mx) res.clear(); + res.add(p.val); + mx = cnt; + } + pre = p; + p = p.right; + } + return res.stream().mapToInt(i->i).toArray(); + } + + } + + public class UnitTest { + + + } + +} diff --git a/src/main/java/find_peak_element/FindPeakElement.java b/src/main/java/find_peak_element/FindPeakElement.java new file mode 100644 index 0000000..7e2478e --- /dev/null +++ b/src/main/java/find_peak_element/FindPeakElement.java @@ -0,0 +1,27 @@ +package find_peak_element; + +import java.util.*; + +import org.junit.*; + +import static org.junit.Assert.*; + +public class FindPeakElement { + + public class Solution { + public int findPeakElement(int[] num) { + assert num.length != 0; + for (int i = 0; i < num.length - 1; i++) { + if (num[i] > num[i + 1]) { + return i; + } + } + return num.length - 1; + } + } + + public static class UnitTest { + + } +} + diff --git a/src/main/java/find_permutation/FindPermutation.java b/src/main/java/find_permutation/FindPermutation.java new file mode 100644 index 0000000..4b6b0a7 --- /dev/null +++ b/src/main/java/find_permutation/FindPermutation.java @@ -0,0 +1,37 @@ +package find_permutation; + +/** + * Created by lxie on 8/28/18. + */ +public class FindPermutation { + public int[] findPermutation(String s) { + int n = s.length(); + int[] res = new int[n+1]; + for (int i = 0; i < n + 1; ++i) res[i] = i + 1; + for (int i = 0; i < n; ++i) { + if (s.charAt(i) == 'D') { + int j = i; + while (s.charAt(i) == 'D' && i < n) ++i; + reverse(res, j, i ); + --i; + } + } + return res; + } + + private void reverse(int[] a, int i, int j) { + while (i < j) { + int t = a[j]; + a[j] = a[i]; + a[i] = t; + i++; j--; + } + } + + public static void main(String[] args) { + FindPermutation f = new FindPermutation(); + int[] res = f.findPermutation("DDIIDI"); + System.out.println(res); + } + +} diff --git a/src/main/java/first_bad_version/FirstBadVersion.java b/src/main/java/first_bad_version/FirstBadVersion.java new file mode 100644 index 0000000..85cfdea --- /dev/null +++ b/src/main/java/first_bad_version/FirstBadVersion.java @@ -0,0 +1,29 @@ +package first_bad_version; + +/** + * Created by lxie on 12/3/17. + */ +public class FirstBadVersion { + + public static class Solution { + public int firstBadVersion(int n) { + int left = 1, right = n; + while (left < right) { + int mid = left + (right - left) / 2; + if (isBadVersion(mid)) right = mid; + else left = mid + 1; + } + return left; + + } + + // stub function here + private boolean isBadVersion(int version) { + return false; + } + } + + public static class UnitTest { + + } +} diff --git a/src/main/java/first_missing_positive/FirstMissingPositive.java b/src/main/java/first_missing_positive/FirstMissingPositive.java index a678dba..771a4ac 100644 --- a/src/main/java/first_missing_positive/FirstMissingPositive.java +++ b/src/main/java/first_missing_positive/FirstMissingPositive.java @@ -2,30 +2,26 @@ public class FirstMissingPositive { - public class Solution { - public int firstMissingPositive(int[] A) { - int n = A.length; - for (int i = 0; i < n; i++) { - if (A[i] <= 0) { - A[i] = n + 1; - } + public int firstMissingPositive(int[] nums) { + int n = nums.length; + for (int i = 0; i < n; ++i) { + while (nums[i] > 0 && nums[i] <= n && nums[nums[i] - 1] != nums[i]) { + int tmp = nums[i]; + nums[i] = nums[nums[i] - 1]; + nums[tmp - 1] = tmp; } - for (int i = 0; i < n; i++) { - int temp = Math.abs(A[i]); - if (temp <= n && A[temp - 1] > 0) { - A[temp - 1] = -A[temp - 1]; - } - } - for (int i = 0; i < n; i++) { - if (A[i] > 0) { - return i + 1; - } - } - return n + 1; } + for (int i = 0; i < n; ++i) { + if (nums[i] != i + 1) return i + 1; + } + return n + 1; } - public static class UnitTest { + public static void main(String[] args) { + FirstMissingPositive f =new FirstMissingPositive(); + int[] a = {3,4,-1,1}; + System.out.println(f.firstMissingPositive(a)); + } } diff --git a/src/main/java/flatten_2d_vector/Flatten2DVector.java b/src/main/java/flatten_2d_vector/Flatten2DVector.java new file mode 100644 index 0000000..05e07bc --- /dev/null +++ b/src/main/java/flatten_2d_vector/Flatten2DVector.java @@ -0,0 +1,37 @@ +package flatten_2d_vector; + +import java.util.Iterator; +import java.util.List; + +/** + * Created by lxie on 11/29/17. + */ +public class Flatten2DVector implements Iterator { + + private Iterator> i; + private Iterator j; + + public Flatten2DVector(List> vec2d) { + // Initialize your data structure here + i = vec2d.iterator(); + j = null; + } + + @Override + public Integer next() { + // Write your code here + hasNext(); + return j.next(); + } + + @Override + public boolean hasNext() { + // Write your code here + while ((j == null || !j.hasNext()) && i.hasNext()) + j = i.next().iterator(); + return j != null && j.hasNext(); + } + + @Override + public void remove() {} +} diff --git a/src/main/java/flatten_nested_list_iterator/FlattenNestListIterator.java b/src/main/java/flatten_nested_list_iterator/FlattenNestListIterator.java new file mode 100644 index 0000000..f68ba6e --- /dev/null +++ b/src/main/java/flatten_nested_list_iterator/FlattenNestListIterator.java @@ -0,0 +1,66 @@ +package flatten_nested_list_iterator; + +import common.NestedInteger; + +import java.util.Iterator; +import java.util.List; +import java.util.Stack; + +/** + * Created by lxie on 9/20/17. + */ +public class FlattenNestListIterator { + + class Solution { + + public class NestedIterator implements Iterator { + + private Stack stack; + + private void pushListToStack(List nestedList) { + Stack temp = new Stack<>(); + for (NestedInteger nested : nestedList) { + temp.push(nested); + } + + while (!temp.isEmpty()) { // in reverse order + stack.push(temp.pop()); + } + } + + public NestedIterator(List nestedList) { + stack = new Stack<>(); + pushListToStack(nestedList); + } + + // @return {int} the next element in the iteration + @Override + public Integer next() { + if (!hasNext()) { + return null; + } + return stack.pop().getInteger(); + } + + // @return {boolean} true if the iteration has more element or false + @Override + public boolean hasNext() { + while (!stack.isEmpty() && !stack.peek().isInteger()) { + pushListToStack(stack.pop().getList()); + } + + return !stack.isEmpty(); + } + + @Override + public void remove() { + } + } + + public void main(String[] args) { + System.out.println("this is for test"); + } + + } + +} diff --git a/src/main/java/flip_game_ii/FlipGameII.java b/src/main/java/flip_game_ii/FlipGameII.java new file mode 100644 index 0000000..e6dee6f --- /dev/null +++ b/src/main/java/flip_game_ii/FlipGameII.java @@ -0,0 +1,24 @@ +package flip_game_ii; + +/** + * Created by lxie on 6/20/18. + */ +public class FlipGameII { + + public class Solution { + + public boolean canWin(String s) { + for (int i = 1; i < s.length(); ++i) { + if (s.charAt(i) == '+' && s.charAt(i-1) == '+' && + !canWin(s.substring(0, i-1) + "--" + s.substring(i + 1))) { + return true; + } + } + return false; + } + } + + public static void main(String[] args) { + + } +} diff --git a/src/main/java/fraction_to_recurring_decimal/FractiontoRecurringDecimal.java b/src/main/java/fraction_to_recurring_decimal/FractiontoRecurringDecimal.java new file mode 100644 index 0000000..104a52f --- /dev/null +++ b/src/main/java/fraction_to_recurring_decimal/FractiontoRecurringDecimal.java @@ -0,0 +1,55 @@ +package fraction_to_recurring_decimal; + +import org.junit.Test; + +import java.util.HashMap; +import java.util.Map; + +import static org.junit.Assert.assertEquals; + +public class FractiontoRecurringDecimal { + + public class Solution { + + public String fractionToDecimal(int numerator, int denominator) { + int s1 = numerator >= 0 ? 1 : -1; + int s2 = denominator >= 0 ? 1 : -1; + long num = Math.abs((long)numerator); + long den = Math.abs((long)denominator); + long out = num / den; + long rem = num % den; + Map m = new HashMap<>(); + String res = Long.toString(out); + if (s1 * s2 == -1 && (out > 0 || rem > 0)) res = "-" + res; + if (rem == 0) return res; + res += "."; + StringBuilder s = new StringBuilder(""); + int pos = 0; + while (rem != 0) { + if (m.containsKey(rem)) { + s.insert(m.get(rem), "("); + s.append(")"); + return res + s; + } + m.put(rem, pos); + s.append(Long.toString((rem * 10) / den)); + rem = (rem * 10) % den; + ++pos; + } + return res + s; + } + } + + public static class UnitTest { + + @Test + public void testFractionToDecimal() { + Solution s = new FractiontoRecurringDecimal().new Solution(); + assertEquals("3.(3)", s.fractionToDecimal(10, 3)); + assertEquals("0.75", s.fractionToDecimal(3, 4)); + assertEquals("0.(09)", s.fractionToDecimal(1, 11)); + assertEquals("0.0000000004656612873077392578125", s.fractionToDecimal(-1, -2147483648)); + } + } +} + diff --git a/src/main/java/freedom_trail/FreedomTrail.java b/src/main/java/freedom_trail/FreedomTrail.java new file mode 100644 index 0000000..eebfce3 --- /dev/null +++ b/src/main/java/freedom_trail/FreedomTrail.java @@ -0,0 +1,33 @@ +package freedom_trail; + +/** + * Created by lxie on 9/20/18. + */ +public class FreedomTrail { + + public class Solution { + + public int findRotateSteps(String ring, String key) { + int n = ring.length(), m = key.length(); + int[][] dp = new int[m+1][n]; + for (int i = m - 1; i >= 0; --i) { + for (int j = 0; j < n; ++j) { + dp[i][j] = Integer.MAX_VALUE; + for (int k = 0; k < n; ++k) { + if (ring.charAt(k) == key.charAt(i)) { + int diff = Math.abs(j - k); + int step = Math.min(diff, n - diff); + dp[i][j] = Math.min(dp[i][j], step + dp[i + 1][k]); + } + } + } + } + return dp[0][0] + m; + } + } + + public class UnitTest { + + } + +} diff --git a/src/main/java/frog_jump/FrogJump.java b/src/main/java/frog_jump/FrogJump.java new file mode 100644 index 0000000..d2f78f9 --- /dev/null +++ b/src/main/java/frog_jump/FrogJump.java @@ -0,0 +1,72 @@ +package frog_jump; + +import java.util.HashMap; +import java.util.HashSet; + +/** + * Created by lxie on 9/14/17. + */ +public class FrogJump { + + class Solution { + + public boolean canCross(int[] stones) { + HashMap m = new HashMap<>(); + return helper(stones, 0, 0, m); + } + + public boolean helper(int[] stones, int pos, int jump, HashMap m) { + int n = stones.length, key = pos | jump << 11; // 11 means a big left shift + if (pos >= n - 1) return true; + if (m.containsKey(key)) return m.get(key); + for (int i = pos + 1; i < n; ++i) { + int dist = stones[i] - stones[pos]; + if (dist < jump - 1) continue; + if (dist > jump + 1) { + m.put(key, false); + return false; + } + if (helper(stones, i, dist, m)) { + m.put(key, true); + return true; + } + } + m.put(key, false); + return false; + } + + public boolean canCrossDP(int[] stones) { + HashMap> dp = + new HashMap>(stones.length); + for (int i = 0; i < stones.length; i++) { + dp.put(stones[i], new HashSet() ); + } + dp.get(0).add(0); + + for (int i = 0; i < stones.length - 1; ++i) { + int stone = stones[i]; + for (int k : dp.get(stone)) { + // k - 1 + if (k - 1 > 0 && dp.containsKey(stone + k - 1)) + dp.get(stone + k - 1).add(k - 1); + // k + if (dp.containsKey(stone + k)) + dp.get(stone + k).add(k); + // k + 1 + if (dp.containsKey(stone + k + 1)) + dp.get(stone + k + 1).add(k + 1); + } + } + + return !dp.get(stones[stones.length - 1]).isEmpty(); + } + + } + + + public static void main(String[] args) { + System.out.println("this is for test"); + } + + +} \ No newline at end of file diff --git a/src/main/java/game_of_life/GameOfLife.java b/src/main/java/game_of_life/GameOfLife.java new file mode 100644 index 0000000..7505c7e --- /dev/null +++ b/src/main/java/game_of_life/GameOfLife.java @@ -0,0 +1,39 @@ +package game_of_life; + +/** + * Created by lxie on 6/17/18. + */ +public class GameOfLife { + + public class Solution { + + public void gameOfLife(int[][] board) { + int m = board.length, n = (m != 0) ? board[0].length : 0; + int dx[] = {-1, -1, -1, 0, 1, 1, 1, 0}; + int dy[] = {-1, 0, 1, 1, 1, 0, -1, -1}; + for (int i = 0; i < m; ++i) { + for (int j = 0; j < n; ++j) { + int cnt = 0; + for (int k = 0; k < 8; ++k) { + int x = i + dx[k], y = j + dy[k]; + if (x >= 0 && x < m && y >= 0 && y < n && (board[x][y] == 1 || board[x][y] == 2)) { + ++cnt; + } + } + if (board[i][j] != 0 && (cnt < 2 || cnt > 3)) board[i][j] = 2; + else if (board[i][j] == 0 && cnt == 3) board[i][j] = 3; + } + } + for (int i = 0; i < m; ++i) { + for (int j = 0; j < n; ++j) { + board[i][j] %= 2; + } + } + } + + } + + public class UnitTest { + + } +} diff --git a/src/main/java/gas_station/GasStation.java b/src/main/java/gas_station/GasStation.java index ab4c4cc..34ec7e7 100644 --- a/src/main/java/gas_station/GasStation.java +++ b/src/main/java/gas_station/GasStation.java @@ -4,26 +4,17 @@ public class GasStation { public class Solution { public int canCompleteCircuit(int[] gas, int[] cost) { - int start = 0; - while (start < gas.length) { - int end = start; - int rest = 0; - do { - rest += gas[end] - cost[end]; - end = (end + 1) % gas.length; - if (rest < 0) { - if (end <= start) { - return -1; - } - break; - } - } while (end != start); - if (end == start) { - return start; + int total = 0, sum = 0, start = 0; + for (int i = 0; i < gas.length; ++i) { + total += gas[i] - cost[i]; + sum += gas[i] - cost[i]; + if (sum < 0) { + start = i + 1; + sum = 0; } - start = end; } - return -1; + if (total < 0) return -1; + else return start; } } diff --git a/src/main/java/generalized_abbreviation/GeneralizedAbbreviation.java b/src/main/java/generalized_abbreviation/GeneralizedAbbreviation.java new file mode 100644 index 0000000..d3540c2 --- /dev/null +++ b/src/main/java/generalized_abbreviation/GeneralizedAbbreviation.java @@ -0,0 +1,40 @@ +package generalized_abbreviation; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by lxie on 7/3/18. + */ +public class GeneralizedAbbreviation { + + public static class Solution { + + public List generateAbbreviations(String word) { + List res = new ArrayList<>(); + for (int i = 0; i < Math.pow(2, word.length()); ++i) { + String out = ""; + int cnt = 0; + for (int j = 0; j < word.length(); ++j) { + if (((i >> j) & 1) == 1) ++cnt; + else { + if (cnt != 0) { + out += Integer.toString(cnt); + cnt = 0; + } + out += word.charAt(j); + } + } + if (cnt > 0) out += Integer.toString(cnt); + res.add(out); + } + return res; + } + + } + + public static void main (String[] args) { + Solution sol = new Solution(); + System.out.println("result is " + sol.generateAbbreviations("word")); + } +} diff --git a/src/main/java/generate_parentheses/GenerateParentheses.java b/src/main/java/generate_parentheses/GenerateParentheses.java index ea5193e..f372435 100644 --- a/src/main/java/generate_parentheses/GenerateParentheses.java +++ b/src/main/java/generate_parentheses/GenerateParentheses.java @@ -1,30 +1,24 @@ package generate_parentheses; import java.util.ArrayList; -import java.util.Arrays; +import java.util.List; public class GenerateParentheses { public class Solution { - private void generateParenthesis(ArrayList ans, char[] s, - int left, int right, int n) { - if (left == n) { - Arrays.fill(s, left + right, n << 1, ')'); - ans.add(new String(s)); + public List generateParenthesis(int n) { + List res = new ArrayList(); + helper(n, n, "", res); + return res; + } + void helper(int left, int right, String out, List res) { + if (left < 0 || right < 0 || left > right) return; + if (left == 0 && right == 0) { + res.add(out); return; } - s[left + right] = '('; - generateParenthesis(ans, s, left + 1, right, n); - if (left > right) { - s[left + right] = ')'; - generateParenthesis(ans, s, left, right + 1, n); - } - } - - public ArrayList generateParenthesis(int n) { - ArrayList ans = new ArrayList(); - generateParenthesis(ans, new char[n << 1], 0, 0, n); - return ans; + helper(left - 1, right, out + "(", res); + helper(left, right - 1, out + ")", res); } } diff --git a/src/main/java/graph_valid_tree/GraphValidTree.java b/src/main/java/graph_valid_tree/GraphValidTree.java new file mode 100644 index 0000000..5e7fb19 --- /dev/null +++ b/src/main/java/graph_valid_tree/GraphValidTree.java @@ -0,0 +1,118 @@ +package graph_valid_tree; + +import java.util.*; + +/** + * Created by lxie on 6/5/18. + */ +public class GraphValidTree { + + // Note - if edge number is n then either 1. all connected, or 2. no loop should work + // version 1: BFS + public class SolutionBFS { + + public boolean validTree(int n, int[][] edges) { + if (n == 0) { + return false; + } + + if (edges.length != n - 1) { + return false; + } + + Map> graph = initializeGraph(n, edges); + + // bfs + Queue queue = new LinkedList<>(); + Set hash = new HashSet<>(); + + queue.offer(0); + hash.add(0); + while (!queue.isEmpty()) { + int node = queue.poll(); + for (Integer neighbor : graph.get(node)) { + if (hash.contains(neighbor)) { + continue; + } + hash.add(neighbor); + queue.offer(neighbor); + } + } + + return (hash.size() == n); + } + + private Map> initializeGraph(int n, int[][] edges) { + Map> graph = new HashMap<>(); + for (int i = 0; i < n; i++) { + graph.put(i, new HashSet()); + } + + for (int i = 0; i < edges.length; i++) { + int u = edges[i][0]; + int v = edges[i][1]; + graph.get(u).add(v); + graph.get(v).add(u); + } + + return graph; + } + } + + + // version 2: Union Find + public class SolutionUnion { + class UnionFind{ + HashMap father = new HashMap(); + UnionFind(int n){ + for(int i = 0 ; i < n; i++) { + father.put(i, i); + } + } + int compressed_find(int x){ + int parent = father.get(x); + while(parent!=father.get(parent)) { + parent = father.get(parent); + } + int temp = -1; + int fa = father.get(x); + while(fa!=father.get(fa)) { + temp = father.get(fa); + father.put(fa, parent) ; + fa = temp; + } + return parent; + + } + + void union(int x, int y){ + int fa_x = compressed_find(x); + int fa_y = compressed_find(y); + if(fa_x != fa_y) + father.put(fa_x, fa_y); + } + } + /** + * @param n an integer + * @param edges a list of undirected edges + * @return true if it's a valid tree, or false + */ + public boolean validTree(int n, int[][] edges) { + // tree should have n nodes with n-1 edges + if (n - 1 != edges.length) { + return false; + } + + UnionFind uf = new UnionFind(n); + + for (int i = 0; i < edges.length; i++) { + if (uf.compressed_find(edges[i][0]) == uf.compressed_find(edges[i][1])) { + return false; + } + uf.union(edges[i][0], edges[i][1]); + } + return true; + } + } + +} diff --git a/src/main/java/group_shifted_string/GroupShiftedString.java b/src/main/java/group_shifted_string/GroupShiftedString.java new file mode 100644 index 0000000..46e8554 --- /dev/null +++ b/src/main/java/group_shifted_string/GroupShiftedString.java @@ -0,0 +1,43 @@ +package group_shifted_string; + +import java.util.*; + +/** + * Created by lxie on 3/19/18. + */ +public class GroupShiftedString { + + public static class Solution { + + List> groupStrings(List strings) { + List> res = new ArrayList<>(); + Map> m = new HashMap<>(); + for (String a : strings) { + String t = ""; + for (char c : a.toCharArray()) { + t += Integer.toString((c + 26 - a.toCharArray()[0]) % 26) + ","; + } + if (!m.containsKey(t)) { + TreeSet tset = new TreeSet<>(); + tset.add(a); + m.put(t, tset); + } else { + m.get(t).add(a); + } + } + for (Map.Entry> entry : m.entrySet()) { + res.add(new ArrayList<>(entry.getValue())); + } + return res; + } + } + + public static void main(String[] args) { + System.out.println("this is for test"); + Solution s = new Solution(); + List strings = new ArrayList(Arrays.asList( + "abc", "bcd", "acef", "xyz", "az", "ba", "a", "z")); + System.out.println(s.groupStrings(strings)); + } + +} diff --git a/src/main/java/guess_number_ii/GuessNumberII.java b/src/main/java/guess_number_ii/GuessNumberII.java new file mode 100644 index 0000000..69ce668 --- /dev/null +++ b/src/main/java/guess_number_ii/GuessNumberII.java @@ -0,0 +1,31 @@ +package guess_number_ii; + +/** + * Created by lxie on 1/28/18. + */ +public class GuessNumberII { + + public class Solution { + public int getMoneyAmount(int n) { + int[][] dp = new int[n+1][n+1]; + for (int i = 2; i <= n; ++i) { + for (int j = i - 1; j > 0; --j) { + int global_min = Integer.MAX_VALUE; + for (int k = j + 1; k < i; ++k) { + int local_max = k + Integer.max(dp[j][k - 1], dp[k + 1][i]); + global_min = Integer.min(global_min, local_max); + } + dp[j][i] = j + 1 == i ? j : global_min; + } + } + return dp[1][n]; + } + + } + + public static class UnitTest { + + } + + +} diff --git a/src/main/java/h_index/HIndex.java b/src/main/java/h_index/HIndex.java new file mode 100644 index 0000000..c62abd5 --- /dev/null +++ b/src/main/java/h_index/HIndex.java @@ -0,0 +1,28 @@ +package h_index; + +import java.util.Collections; +import java.util.List; + +/** + * Created by lxie on 6/14/18. + */ +public class HIndex { + + public class Solution { + + int hIndex(List citations) { + Collections.sort(citations, Collections.reverseOrder()); + + for (int i = 0; i < citations.size(); ++i) { + if (i >= citations.get(i)) return i; + } + return citations.size(); + } + } + + public class UnitTest { + + } + + +} diff --git a/src/main/java/h_index_ii/HIndexII.java b/src/main/java/h_index_ii/HIndexII.java new file mode 100644 index 0000000..9f2ea80 --- /dev/null +++ b/src/main/java/h_index_ii/HIndexII.java @@ -0,0 +1,26 @@ +package h_index_ii; + +/** + * Created by lxie on 6/14/18. + */ +public class HIndexII { + + public class Solution { + + public int hIndex(int[] citations) { + int len = citations.length, left = 0, right = len - 1; + while (left <= right) { + int mid = (left + right)/2; + if (citations[mid] == len - mid) return len - mid; + else if (citations[mid] > len - mid) right = mid - 1; + else left = mid + 1; + } + return len - left; + } + } + + public class UnitTest { + + } + +} diff --git a/src/main/java/happy_number/HappyNumber.java b/src/main/java/happy_number/HappyNumber.java new file mode 100644 index 0000000..7291eb1 --- /dev/null +++ b/src/main/java/happy_number/HappyNumber.java @@ -0,0 +1,31 @@ +package happy_number; + +import java.util.HashSet; +import java.util.Set; + +/** + * Created by lxie on 8/17/18. + */ +public class HappyNumber { + + public class Solution { + boolean isHappy(int n) { + Set s = new HashSet<>(); + while (n != 1) { + int t = 0; + while (n != 0) { + t += (n % 10) * (n % 10); + n /= 10; + } + n = t; + if (s.contains(n)) break; + else s.add(n); + } + return n == 1; + } + } + + public class UnitTest { + + } +} diff --git a/src/main/java/heaters/Heaters.java b/src/main/java/heaters/Heaters.java new file mode 100644 index 0000000..bc47e67 --- /dev/null +++ b/src/main/java/heaters/Heaters.java @@ -0,0 +1,32 @@ +package heaters; + +import java.util.Arrays; + +/** + * Created by lxie on 9/2/18. + */ +public class Heaters { + + public class Solution { + + public int findRadius(int[] houses, int[] heaters) { + int n = heaters.length, j = 0, res = 0; + Arrays.sort(houses); + Arrays.sort(heaters); + for (int i = 0; i < houses.length; ++i) { + int cur = houses[i]; + while (j < n - 1 && Math.abs(heaters[j + 1] - cur) <= Math.abs(heaters[j] - cur)) { + ++j; + } + res = Math.max(res, Math.abs(heaters[j] - cur)); + } + return res; + } + + } + + public class UnitTest { + + } + +} diff --git a/src/main/java/house_robber/HouseRobber.java b/src/main/java/house_robber/HouseRobber.java new file mode 100644 index 0000000..41f9a33 --- /dev/null +++ b/src/main/java/house_robber/HouseRobber.java @@ -0,0 +1,21 @@ +package house_robber; + +public class HouseRobber { + + public class Solution { + public int rob(int[] nums) { + if (nums.length <= 1) return nums.length == 0 ? 0 : nums[0]; + int[] dp = new int[nums.length]; + dp[0] = nums[0]; dp[1] = Integer.max(nums[0], nums[1]); + for (int i = 2; i < nums.length; ++i) { + dp[i] = Integer.max(nums[i] + dp[i - 2], dp[i - 1]); + } + return dp[nums.length - 1]; + } + } + + public static class UnitTest { + + } +} + diff --git a/src/main/java/house_robber_II/HouseRobberII.java b/src/main/java/house_robber_II/HouseRobberII.java new file mode 100644 index 0000000..fb06d2f --- /dev/null +++ b/src/main/java/house_robber_II/HouseRobberII.java @@ -0,0 +1,31 @@ +package house_robber_II; + +/** + * Created by lxie on 12/4/17. + */ +public class HouseRobberII { + + public class Solution { + public int rob(int[] nums) { + if (nums.length <= 1) return nums.length == 0 ? 0 : nums[0]; + + return Integer.max(rob(nums, 0, nums.length - 2), rob(nums, 1, nums.length - 1)); + } + + int rob(int[]nums, int left, int right) { + if (right == left) return nums[left]; + int[] dp = new int[right + 1]; + dp[left] = nums[left]; + dp[left + 1] = Integer.max(nums[left], nums[left + 1]); + for (int i = left + 2; i <= right; ++i) { + dp[i] = Integer.max(nums[i] + dp[i - 2], dp[i - 1]); + } + return dp[right]; + } + + } + + public static class UnitTest { + + } +} diff --git a/src/main/java/house_robber_III/HouseRobberIII.java b/src/main/java/house_robber_III/HouseRobberIII.java new file mode 100644 index 0000000..d0d9026 --- /dev/null +++ b/src/main/java/house_robber_III/HouseRobberIII.java @@ -0,0 +1,39 @@ +package house_robber_III; + +import common.TreeNode; + +import java.util.HashMap; +import java.util.Map; + +/** + * Created by lxie on 12/5/17. + */ +public class HouseRobberIII { + + public class Solution { + public int rob(TreeNode root) { + Map m = new HashMap(); + return dfs(root, m); + } + + int dfs(TreeNode root, Map m) { + if (root == null) return 0; + if (m.containsKey(root)) return m.get(root); + int val = 0; + if (root.left != null) { + val += dfs(root.left.left, m) + dfs(root.left.right, m); + } + if (root.right != null) { + val += dfs(root.right.left, m) + dfs(root.right.right, m); + } + val = Integer.max(val + root.val, dfs(root.left, m) + dfs(root.right, m)); + m.put(root, val); + return val; + } + + } + + public static class UnitTest { + + } +} diff --git a/src/main/java/implement_magic_dictionary/MagicDictionary.java b/src/main/java/implement_magic_dictionary/MagicDictionary.java new file mode 100644 index 0000000..adb6ee8 --- /dev/null +++ b/src/main/java/implement_magic_dictionary/MagicDictionary.java @@ -0,0 +1,43 @@ +package implement_magic_dictionary; + +import java.util.HashSet; +import java.util.Set; + +/** + * Created by lxie on 9/15/18. + */ +public class MagicDictionary { + + private Set s = new HashSet<>(); + + /** Build a dictionary through a list of words */ + public void buildDict(String[] dict) { + for (String word : dict) s.add(word); + } + + /** Returns if there is any word in the trie that equals to the given word after modifying exactly one character */ + boolean search(String word) { + char[] word1 = word.toCharArray(); + for (int i = 0; i < word1.length; ++i) { + char t = word1[i]; + for (char c = 'a'; c <= 'z'; ++c) { + if (c == t) continue; + word1[i] = c; + if (s.contains(new String(word1))) return true; + } + word1[i] = t; + } + return false; + } + + public static void main(String[] args) { + MagicDictionary m = new MagicDictionary(); + String[] dict = {"hello", "leetcode"}; + m.buildDict(dict); + System.out.println(m.search("hello")); + System.out.println(m.search("hhllo")); + System.out.println(m.search("hell")); + System.out.println(m.search("leetcoded")); + } + +} diff --git a/src/main/java/implement_queue_using_stacks/QueueUsingStacks.java b/src/main/java/implement_queue_using_stacks/QueueUsingStacks.java new file mode 100644 index 0000000..38e523e --- /dev/null +++ b/src/main/java/implement_queue_using_stacks/QueueUsingStacks.java @@ -0,0 +1,54 @@ +package implement_queue_using_stacks; + +import java.util.Stack; + +/** + * Created by lxie on 3/5/18. + */ +public class QueueUsingStacks { + + class MyQueue { + + private Stack s = new Stack<>(); + + /** Initialize your data structure here. */ + public MyQueue() { + + } + + /** Push element x onto stack. */ + public void push(int x) { + Stack tmp = new Stack<>(); + while (!s.isEmpty()) { + tmp.push(s.peek()); + s.pop(); + } + s.push(x); + while (!tmp.isEmpty()) { + s.push(tmp.peek()); + tmp.pop(); + } + + } + + /** Removes the element on top of the stack and returns that element. */ + public int pop() { + return s.pop(); + } + + /** Get the top element. */ + public int peek() { + return s.peek(); + } + + /** Returns whether the stack is empty. */ + public boolean empty() { + return s.isEmpty(); + } + } + + public static class UnitTest { + + } + +} diff --git a/src/main/java/implement_stack_using_queues/StackUsingQueues.java b/src/main/java/implement_stack_using_queues/StackUsingQueues.java new file mode 100644 index 0000000..a314337 --- /dev/null +++ b/src/main/java/implement_stack_using_queues/StackUsingQueues.java @@ -0,0 +1,54 @@ +package implement_stack_using_queues; + +import java.util.LinkedList; +import java.util.Queue; + +/** + * Created by lxie on 2/15/18. + */ +public class StackUsingQueues { + + class MyStack { + + private Queue q = new LinkedList<>(); + + /** Initialize your data structure here. */ + public MyStack() { + + } + + /** Push element x onto stack. */ + public void push(int x) { + Queue tmp = new LinkedList<>(); + while (!q.isEmpty()) { + tmp.add(q.peek()); + q.remove(); + } + q.add(x); + while (!tmp.isEmpty()) { + q.add(tmp.peek()); + tmp.remove(); + } + + } + + /** Removes the element on top of the stack and returns that element. */ + public int pop() { + return q.remove(); + } + + /** Get the top element. */ + public int top() { + return q.peek(); + } + + /** Returns whether the stack is empty. */ + public boolean empty() { + return q.isEmpty(); + } + } + + public static class UnitTest { + + } +} diff --git a/src/main/java/implement_strstr/ImplementstrStr.java b/src/main/java/implement_strstr/ImplementstrStr.java index 7726842..abef036 100644 --- a/src/main/java/implement_strstr/ImplementstrStr.java +++ b/src/main/java/implement_strstr/ImplementstrStr.java @@ -3,23 +3,8 @@ public class ImplementstrStr { public class Solution { - public String strStr(String haystack, String needle) { - if (haystack == null || needle == null) { - return null; - } - for (int i = 0; i <= haystack.length() - needle.length(); i++) { - boolean find = true; - for (int j = 0; j < needle.length(); j++) { - if (haystack.charAt(i + j) != needle.charAt(j)) { - find = false; - break; - } - } - if (find) { - return haystack.substring(i); - } - } - return null; + public int strStr(String haystack, String needle) { + return haystack.indexOf(needle); } } diff --git a/src/main/java/implement_trie/ImplementTrie.java b/src/main/java/implement_trie/ImplementTrie.java new file mode 100644 index 0000000..dd867bc --- /dev/null +++ b/src/main/java/implement_trie/ImplementTrie.java @@ -0,0 +1,60 @@ +package implement_trie; + +public class ImplementTrie { + + class TrieNode { + public TrieNode[] child = new TrieNode[26]; + public boolean isWord; + + public void TrieNode() { + for (TrieNode a : child) a = null; + } + + } + + public class Trie { + private TrieNode root = null; + + public Trie() { + root = new TrieNode(); + } + + // Inserts a word into the trie. + public void insert(String s) { + TrieNode p = root; + for (char a : s.toCharArray()) { + int i = a - 'a'; + if (p.child[i] == null) + p.child[i] = new TrieNode(); + p = p.child[i]; + } + p.isWord = true; + } + + // Returns if the word is in the trie. + public boolean search(String key) { + TrieNode p = root; + for (char a : key.toCharArray()) { + int i = a - 'a'; + if (p.child[i] == null) return false; + p = p.child[i]; + } + return p.isWord; + } + + // Returns if there is any word in the trie + // that starts with the given prefix. + public boolean startsWith(String prefix) { + TrieNode p = root; + for (char a : prefix.toCharArray()) { + int i = a - 'a'; + if (p.child[i] == null) return false; + p = p.child[i]; + } + return true; + } + + } + +} + diff --git a/src/main/java/increasing_triplet_subsequence/IncreasingTripletSubsequence.java b/src/main/java/increasing_triplet_subsequence/IncreasingTripletSubsequence.java new file mode 100644 index 0000000..8458e53 --- /dev/null +++ b/src/main/java/increasing_triplet_subsequence/IncreasingTripletSubsequence.java @@ -0,0 +1,26 @@ +package increasing_triplet_subsequence; + +/** + * Created by lxie on 9/30/18. + */ +public class IncreasingTripletSubsequence { + + public class Solution { + + boolean increasingTriplet(int[] nums) { + int m1 = Integer.MAX_VALUE, m2 = Integer.MAX_VALUE; + for (int a : nums) { + if (m1 >= a) m1 = a; // m1 leaves INT_MAX ealier than m2 + else if (m2 >= a) m2 = a; + else return true; + } + return false; + } + } + + public class UnitTest { + + + } + +} diff --git a/src/main/java/inorder_successor/InorderSuccessor.java b/src/main/java/inorder_successor/InorderSuccessor.java new file mode 100644 index 0000000..5076228 --- /dev/null +++ b/src/main/java/inorder_successor/InorderSuccessor.java @@ -0,0 +1,27 @@ +package inorder_successor; + +import common.TreeNode; + +/** + * Created by lxie on 6/16/18. + */ +public class InorderSuccessor { + + public class Solution { + + public TreeNode inorderSuccessor(TreeNode root, TreeNode p) { + TreeNode res = null; + while (root != null) { + if (root.val > p.val) { + res = root; + root = root.left; + } else root = root.right; + } + return res; + } + } + + public class UnitTest { + + } +} diff --git a/src/main/java/insert_delete_random/RandomizedSet.java b/src/main/java/insert_delete_random/RandomizedSet.java new file mode 100644 index 0000000..8410522 --- /dev/null +++ b/src/main/java/insert_delete_random/RandomizedSet.java @@ -0,0 +1,73 @@ +package insert_delete_random; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Created by lxie on 9/22/17. + */ +public class RandomizedSet { + + private List nums = new ArrayList<>(); + private Map m = new HashMap<>(); + + /** Initialize your data structure here. */ + public RandomizedSet() {} + + /** Inserts a value to the set. Returns true if the set did not already contain the specified element. */ + public boolean insert(int val) { + if (m.containsKey(val)) return false; + nums.add(val); + m.put(val, nums.size() - 1); + return true; + } + + /** Removes a value from the set. Returns true if the set contained the specified element. */ + public boolean remove(int val) { + if (!m.containsKey(val)) return false; + int last = nums.get(nums.size()-1); + m.put(last, m.get(val)); + nums.set(m.get(val), last); + nums.remove(nums.size() - 1); + m.remove(val); + return true; + } + + /** Get a random element from the set. */ + int getRandom() { + return nums.get((int)Math.random() % nums.size()); + } + + + + public static void main(String[] args) { + System.out.println("this is for test"); + RandomizedSet randomSet = new RandomizedSet(); + + // Inserts 1 to the set. Returns true as 1 was inserted successfully. + System.out.println("randomSet.insert(1) -> " + randomSet.insert(1)); + + // Returns false as 2 does not exist in the set. + System.out.println("randomSet.remove(2) -> " + randomSet.remove(2)); + + // Inserts 2 to the set, returns true. Set now contains [1,2]. + System.out.println("randomSet.insert(2) -> " + randomSet.insert(2)); + + // getRandom should return either 1 or 2 randomly. + System.out.println("randomSet.getRandom() -> " + randomSet.getRandom()); + + // Removes 1 from the set, returns true. Set now contains [2]. + System.out.println("randomSet.remove(1) -> " + randomSet.remove(1)); + + // 2 was already in the set, so return false. + System.out.println("randomSet.insert(2) -> " + randomSet.insert(2)); + + // Since 2 is the only number in the set, getRandom always return 2. + System.out.println("randomSet.getRandom() -> " + randomSet.getRandom()); + + } + + +} diff --git a/src/main/java/insert_delete_random_II/RandomizedCollection.java b/src/main/java/insert_delete_random_II/RandomizedCollection.java new file mode 100644 index 0000000..eceb7dc --- /dev/null +++ b/src/main/java/insert_delete_random_II/RandomizedCollection.java @@ -0,0 +1,83 @@ +package insert_delete_random_II; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Created by lxie on 9/23/17. + */ +public class RandomizedCollection { + private Map> map; + private List nums; + + /** Initialize your data structure here. */ + public RandomizedCollection() { + map = new HashMap<>(); + nums = new ArrayList<>(); + } + + /** Inserts a value to the collection. Returns true if the collection did not already contain the specified element. */ + public boolean insert(int val) { + boolean res = !map.containsKey(val); + if(res) map.put(val, new ArrayList<>()); + map.get(val).add(nums.size()); + nums.add(new int[]{val, map.get(val).size() - 1}); + return res; + } + + /** Removes a value from the collection. Returns true if the collection contained the specified element. */ + public boolean remove(int val) { + boolean res = map.containsKey(val); + if(res) { + List valList = map.get(val); + int valLastIndex = valList.get(valList.size() - 1); // always take the last one + + int[] swapNum = nums.get(nums.size() - 1); + int swapVal = swapNum[0], swapIndex = swapNum[1]; + + map.get(swapVal).set(swapIndex, valLastIndex); // set it to same pos + nums.set(valLastIndex, swapNum); + + if(valList.size() == 1) map.remove(val); + else valList.remove(valList.size() - 1); + + nums.remove(nums.size() - 1); + } + return res; + } + + /** Get a random element from the collection. */ + int getRandom() { + return nums.get((int)Math.random() % nums.size())[0]; + } + + public static void main(String[] args) { + System.out.println("this is for test"); + /* RandomizedCollection randomSet = new RandomizedCollection(); + + // Inserts 1 to the set. Returns true as 1 was inserted successfully. + System.out.println("randomSet.insert(1) -> " + randomSet.insert(1)); + + // Returns false as 2 does not exist in the set. + System.out.println("randomSet.remove(2) -> " + randomSet.remove(2)); + + // Inserts 2 to the set, returns true. Set now contains [1,2]. + System.out.println("randomSet.insert(2) -> " + randomSet.insert(2)); + + // getRandom should return either 1 or 2 randomly. + System.out.println("randomSet.getRandom() -> " + randomSet.getRandom()); + + // Removes 1 from the set, returns true. Set now contains [2]. + System.out.println("randomSet.remove(1) -> " + randomSet.remove(1)); + + // 2 was already in the set, so return false. + System.out.println("randomSet.insert(2) -> " + randomSet.insert(2)); + + // Since 2 is the only number in the set, getRandom always return 2. + System.out.println("randomSet.getRandom() -> " + randomSet.getRandom()); */ + + } + +} diff --git a/src/main/java/insert_interval/InsertInterval.java b/src/main/java/insert_interval/InsertInterval.java new file mode 100644 index 0000000..8c616e7 --- /dev/null +++ b/src/main/java/insert_interval/InsertInterval.java @@ -0,0 +1,47 @@ +package insert_interval; + +import common.Interval; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import static org.junit.Assert.assertEquals; + +public class InsertInterval { + + public class Solution { + + public List insert(List intervals, Interval newInterval) { + List newIntervals = new ArrayList(); + for (Interval interval : intervals) { + if (newInterval == null || interval.end < newInterval.start) { + newIntervals.add(interval); + } else if (interval.start > newInterval.end) { + newIntervals.add(newInterval); + newIntervals.add(interval); + newInterval = null; + } else { + newInterval.start = Math.min(newInterval.start, interval.start); + newInterval.end = Math.max(newInterval.end, interval.end); + } + } + if (newInterval != null) { + newIntervals.add(newInterval); + } + return newIntervals; + } + } + + public static class UnitTest { + + @Test + public void testInsert() { + Solution s = new InsertInterval().new Solution(); + assertEquals( + Arrays.asList(new Interval(0, 0), new Interval(1, 5)), + s.insert(Arrays.asList(new Interval(1, 5)), new Interval(0, 0))); + } + } +} diff --git a/src/main/java/insertion_sort_list/InsertionSortList.java b/src/main/java/insertion_sort_list/InsertionSortList.java new file mode 100644 index 0000000..05a35a8 --- /dev/null +++ b/src/main/java/insertion_sort_list/InsertionSortList.java @@ -0,0 +1,32 @@ +package insertion_sort_list; + +import common.ListNode; + +public class InsertionSortList { + + public class Solution { + public ListNode insertionSortList(ListNode head) { + ListNode dummy = new ListNode(0); + ListNode p = head; + while (p != null) { + ListNode pre = dummy; + while (pre.next != null) { + if (pre.next.val <= p.val) { // stable sort + pre = pre.next; + } else { + break; + } + } + ListNode temp = p.next; + p.next = pre.next; + pre.next = p; + p = temp; + } + return dummy.next; + } + } + + public static class UnitTest { + + } +} diff --git a/src/main/java/integer_replacement/IntegerReplacement.java b/src/main/java/integer_replacement/IntegerReplacement.java new file mode 100644 index 0000000..e051bc8 --- /dev/null +++ b/src/main/java/integer_replacement/IntegerReplacement.java @@ -0,0 +1,26 @@ +package integer_replacement; + +/** + * Created by lxie on 11/19/17. + */ +public class IntegerReplacement { + + public static class Solution { + public int integerReplacement(int n) { + if (n == 1) return 0; + if (n % 2 == 0) return 1 + integerReplacement(n / 2); + else { + long t = n; + return 2 + Math.min(integerReplacement((int) ((t + 1) / 2)), + integerReplacement((int) ((t - 1) / 2))); + } + } + + } + + public static void main(String[] args) { + Solution sol = new Solution(); + int n = 2147483647; + System.out.println("result is " + sol.integerReplacement(n)); + } +} diff --git a/src/main/java/integer_to_english_words/NumberToWords.java b/src/main/java/integer_to_english_words/NumberToWords.java new file mode 100644 index 0000000..731bc84 --- /dev/null +++ b/src/main/java/integer_to_english_words/NumberToWords.java @@ -0,0 +1,43 @@ +package integer_to_english_words; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * Created by lxie on 6/13/18. + */ +public class NumberToWords { + + public static class Solution { + + String numberToWords(int num) { + String res = convertHundred(num % 1000); + List v = new ArrayList<>(Arrays.asList("Thousand", "Million", "Billion")); + for (int i = 0; i < 3; ++i) { + num /= 1000; + res = num % 1000 != 0 ? convertHundred(num % 1000) + " " + v.get(i) + " " + res : res; + } + while (res.charAt(res.length()-1) == ' ') res.substring(0, res.length()-1); + return res.isEmpty() ? "Zero" : res; + } + String convertHundred(int num) { + List v1 = new ArrayList<>(Arrays.asList("", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen")); + List v2 = new ArrayList<>(Arrays.asList("", "", "Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety")); + String res; + int a = num / 100, b = num % 100, c = num % 10; + res = b < 20 ? v1.get(b) : v2.get(b / 10) + (c != 0 ? " " + v1.get(c) : ""); + if (a > 0) res = v1.get(a) + " Hundred" + (b != 0 ? " " + res : ""); + return res; + } + } + + public static void main(String[] args) { + System.out.println("this is for test"); + Solution sol = new Solution(); + + System.out.println(sol.numberToWords(1234567)); + + } + +} diff --git a/src/main/java/integer_to_roman/IntegertoRoman.java b/src/main/java/integer_to_roman/IntegertoRoman.java index 00495ad..87ada62 100644 --- a/src/main/java/integer_to_roman/IntegertoRoman.java +++ b/src/main/java/integer_to_roman/IntegertoRoman.java @@ -3,40 +3,26 @@ public class IntegertoRoman { public class Solution { + public String intToRoman(int num) { - private final char[] symbols = new char[] { 'M', 'D', 'C', 'L', 'X', - 'V', 'I' }; + String res = ""; + char roman[] = {'M', 'D', 'C', 'L', 'X', 'V', 'I'}; + int value[] = {1000, 500, 100, 50, 10, 5, 1}; - private String repeat(char c, int times) { - String re = ""; - for (int i = 0; i < times; i++) { - re += c; + for (int n = 0; n < 7; n += 2) { + int x = num / value[n]; + if (x < 4) { + for (int i = 1; i <= x; ++i) res += roman[n]; + } else if (x == 4) res = res + roman[n] + roman[n - 1]; + else if (x > 4 && x < 9) { + res += roman[n - 1]; + for (int i = 6; i <= x; ++i) res += roman[n]; + } else if (x == 9) res = res + roman[n] + roman[n - 2]; + num %= value[n]; } - return re; + return res; } - public String intToRoman(int num) { - String roman = ""; - int scala = 1000; - for (int i = 0; i < symbols.length; i += 2) { - int digit = num / scala; - num %= scala; - scala /= 10; - if (digit == 9) { - roman += symbols[i]; - roman += symbols[i - 2]; - } else if (digit >= 5) { - roman += symbols[i - 1]; - roman += repeat(symbols[i], digit - 5); - } else if (digit == 4) { - roman += symbols[i]; - roman += symbols[i - 1]; - } else { - roman += repeat(symbols[i], digit); - } - } - return roman; - } } public static class UnitTest { diff --git a/src/main/java/interleaving_string/InterleavingString.java b/src/main/java/interleaving_string/InterleavingString.java index 141648b..8b8d0fb 100644 --- a/src/main/java/interleaving_string/InterleavingString.java +++ b/src/main/java/interleaving_string/InterleavingString.java @@ -4,21 +4,26 @@ public class InterleavingString { public class Solution { public boolean isInterleave(String s1, String s2, String s3) { - if (s1.length() + s2.length() != s3.length()) { - return false; + if (s1.length() + s2.length() != s3.length()) return false; + int n1 = s1.length(); + int n2 = s2.length(); + boolean[][] dp = new boolean[n1+1][n2+1]; + dp[0][0] = true; + for (int i = 1; i <= n1; ++i) { + dp[i][0] = dp[i - 1][0] && (s1.charAt(i - 1) == s3.charAt(i - 1)); } - boolean[] dp = new boolean[s2.length() + 1]; - for (int i = 0; i <= s1.length(); i++) { - for (int j = 0; j <= s2.length(); j++) { - dp[j] = (i == 0 && j == 0) - || (i != 0 && dp[j] && s1.charAt(i - 1) == s3 - .charAt(i + j - 1)) - || (j != 0 && dp[j - 1] && s2.charAt(j - 1) == s3 - .charAt(i + j - 1)); + for (int i = 1; i <= n2; ++i) { + dp[0][i] = dp[0][i - 1] && (s2.charAt(i - 1) == s3.charAt(i - 1)); + } + for (int i = 1; i <= n1; ++i) { + for (int j = 1; j <= n2; ++j) { + dp[i][j] = (dp[i - 1][j] && s1.charAt(i - 1) == s3.charAt(i - 1 + j)) || + (dp[i][j - 1] && s2.charAt(j - 1) == s3.charAt(j - 1 + i)); } } - return dp[s2.length()]; + return dp[n1][n2]; } + } public static class UnitTest { diff --git a/src/main/java/intersection_of_two_arrays/IntersectionOfTwoArrays.java b/src/main/java/intersection_of_two_arrays/IntersectionOfTwoArrays.java new file mode 100644 index 0000000..956e1d0 --- /dev/null +++ b/src/main/java/intersection_of_two_arrays/IntersectionOfTwoArrays.java @@ -0,0 +1,38 @@ +package intersection_of_two_arrays; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * Created by lxie on 1/11/18. + */ +public class IntersectionOfTwoArrays { + + public class Solution { + public int[] intersection(int[] nums1, int[] nums2) { + List res = new ArrayList<>(); + Arrays.sort(nums1); Arrays.sort(nums2); + + int i = 0, j = 0; + while (i < nums1.length && j < nums2.length) { + if (nums1[i] < nums2[j]) ++i; + else if (nums1[i] > nums2[j]) ++j; + else { + if (res.size() == 0 || res.get(res.size()-1) != nums1[i]) { + res.add(nums1[i]); + } + ++i; ++j; + } + } + return res.stream().mapToInt(k->k).toArray(); + } + + } + + public static class UnitTest { + + + + } +} diff --git a/src/main/java/intersection_of_two_linked_lists/IntersectionofTwoLinkedLists.java b/src/main/java/intersection_of_two_linked_lists/IntersectionofTwoLinkedLists.java new file mode 100644 index 0000000..383be9a --- /dev/null +++ b/src/main/java/intersection_of_two_linked_lists/IntersectionofTwoLinkedLists.java @@ -0,0 +1,23 @@ +package intersection_of_two_linked_lists; + +import common.ListNode; + +public class IntersectionofTwoLinkedLists { + + public class Solution { + public ListNode getIntersectionNode(ListNode headA, ListNode headB) { + if (headA == null || headB == null) return null; + ListNode a = headA, b = headB; + while (a != b) { + a = (a != null) ? a.next : headB; + b = (b != null) ? b.next : headA; + } + return a; // either intersection or null + } + } + + public static class UnitTest { + + } +} + diff --git a/src/main/java/invert_binary_tree/InvertBinaryTree.java b/src/main/java/invert_binary_tree/InvertBinaryTree.java new file mode 100644 index 0000000..2747f9d --- /dev/null +++ b/src/main/java/invert_binary_tree/InvertBinaryTree.java @@ -0,0 +1,44 @@ +package invert_binary_tree; + +import common.TreeNode; + +import java.util.LinkedList; +import java.util.Queue; + +/** + * Created by lxie on 2/18/18. + */ +public class InvertBinaryTree { + + public class Solution { + public TreeNode invertTree(TreeNode root) { + if (root == null) return null; + TreeNode tmp = root.left; + root.left = invertTree(root.right); + root.right = invertTree(tmp); + return root; + } + + public TreeNode invertTree1(TreeNode root) { + if (root == null) return null; + Queue q = new LinkedList<>(); + q.add(root); + while (!q.isEmpty()) { + TreeNode node = q.peek(); + q.remove(); + TreeNode tmp = node.left; + node.left = node.right; + node.right = tmp; + if (node.left != null) q.add(node.left); + if (node.right != null) q.add(node.right); + } + return root; + } + + } + + public static class UnitTest { + + } + +} diff --git a/src/main/java/island_perimeter/IslandPerimeter.java b/src/main/java/island_perimeter/IslandPerimeter.java new file mode 100644 index 0000000..a5fd931 --- /dev/null +++ b/src/main/java/island_perimeter/IslandPerimeter.java @@ -0,0 +1,31 @@ +package island_perimeter; + +/** + * Created by lxie on 7/6/18. + */ +public class IslandPerimeter { + + public class Solution { + + public int islandPerimeter(int[][] grid) { + if (grid.length == 0 || grid[0].length == 0) return 0; + int m = grid.length, n = grid[0].length, res = 0; + for (int i = 0; i < m; ++i) { + for (int j = 0; j < n; ++j) { + if (grid[i][j] == 0) continue; + if (j == 0 || grid[i][j - 1] == 0) ++res; + if (i == 0 || grid[i - 1][j] == 0) ++res; + if (j == n - 1 || grid[i][j + 1] == 0) ++res; + if (i == m - 1 || grid[i + 1][j] == 0) ++res; + } + } + return res; + } + } + + public class UnitTest { + + + } + +} diff --git a/src/main/java/isomorphic_strings/IsomorphicStrings.java b/src/main/java/isomorphic_strings/IsomorphicStrings.java new file mode 100644 index 0000000..573004c --- /dev/null +++ b/src/main/java/isomorphic_strings/IsomorphicStrings.java @@ -0,0 +1,52 @@ +package isomorphic_strings; + +import java.util.HashMap; +import java.util.Map; + +public class IsomorphicStrings { + + public class Solution { + public boolean isIsomorphic(String str1, String str2) { + if (str1 == null || str2 == null) { + return false; + } + else if (str1.length() != str2.length()) { + return false; + } + else if (str1.length() < 2) { + // lengths are equal; empty string & 1 character strings are isomorphic + return true; + } + else { + char[] str1Chars = str1.toCharArray(); + char[] str2Chars = str2.toCharArray(); + + Map isoMap = new HashMap(); + Map isoMapRev = new HashMap(); + + + int length = str1Chars.length; + for (int index = 0; index < length; index++) { + + Character aCharacterFromFirstWord = str1Chars[index]; + Character aCharacterFromSecondWord = str2Chars[index]; + + if (isoMap.containsKey(aCharacterFromFirstWord)) { + if (!isoMap.get(aCharacterFromFirstWord).equals(aCharacterFromSecondWord)) { + return false; + } + } + else if (isoMapRev.containsKey(aCharacterFromSecondWord)) { + return false; + } else { + isoMap.put(aCharacterFromFirstWord, aCharacterFromSecondWord); + isoMapRev.put(aCharacterFromSecondWord, aCharacterFromFirstWord); + } + } + return true; + } + + } + } +} + diff --git a/src/main/java/jump_game/JumpGame.java b/src/main/java/jump_game/JumpGame.java index 8d41fd7..308efbd 100644 --- a/src/main/java/jump_game/JumpGame.java +++ b/src/main/java/jump_game/JumpGame.java @@ -4,12 +4,12 @@ public class JumpGame { public class Solution { public boolean canJump(int[] A) { - assert A != null; - int far = 0; - for (int i = 0; i < A.length && i <= far; i++) { - far = Math.max(far, A[i] + i); + int[] dp = new int[A.length]; + for (int i = 1; i < A.length; ++i) { + dp[i] = Integer.max(dp[i - 1], A[i - 1]) - 1; + if (dp[i] < 0) return false; } - return far >= A.length - 1; + return dp[A.length - 1] >= 0; } } diff --git a/src/main/java/jump_game_ii/JumpGameII.java b/src/main/java/jump_game_ii/JumpGameII.java index 2e667ef..089b66f 100644 --- a/src/main/java/jump_game_ii/JumpGameII.java +++ b/src/main/java/jump_game_ii/JumpGameII.java @@ -3,19 +3,20 @@ public class JumpGameII { public class Solution { - public int jump(int[] A) { - int step = 0; - int next = 0; - int current = 0; - for (int i = 0; i < A.length; i++) { - if (i > current) { - current = next; - step++; + int jump(int A[]) { + int res = 0, i = 0, cur = 0; + while (cur < A.length - 1) { + int pre = cur; + while (i <= pre) { + cur = Integer.max(cur, i + A[i]); + ++i; } - next = Math.max(next, i + A[i]); + ++res; + if (pre == cur) return -1; // May not need this } - return step; + return res; } + } public static class UnitTest { diff --git a/src/main/java/k_empty_slots/KEmptySlots.java b/src/main/java/k_empty_slots/KEmptySlots.java new file mode 100644 index 0000000..b1175c1 --- /dev/null +++ b/src/main/java/k_empty_slots/KEmptySlots.java @@ -0,0 +1,29 @@ +package k_empty_slots; + +/** + * Created by lxie on 8/18/18. + */ +public class KEmptySlots { + + public class Solution { + + public int kEmptySlots(int[] flowers, int k) { + int res = Integer.MAX_VALUE, left = 0, right = k + 1, n = flowers.length; + int[] days = new int[n]; + for (int i = 0; i < n; ++i) days[flowers[i] - 1] = i + 1; + for (int i = 0; right < n; ++i) { + if (days[i] < days[left] || days[i] <= days[right]) { + if (i == right) res = Math.min(res, Math.max(days[left], days[right])); + left = i; + right = k + 1 + i; + } + } + return (res == Integer.MAX_VALUE) ? -1 : res; + } + } + + public class UnitTest { + + + } +} diff --git a/src/main/java/kth_largest_in_array/KthLargestInArray.java b/src/main/java/kth_largest_in_array/KthLargestInArray.java new file mode 100644 index 0000000..52acbe6 --- /dev/null +++ b/src/main/java/kth_largest_in_array/KthLargestInArray.java @@ -0,0 +1,48 @@ +package kth_largest_in_array; + +/** + * Created by lxie on 9/27/18. + */ +public class KthLargestInArray { + + public class Solution { + + public int findKthLargest(int[] nums, int k) { + int left = 0, right = nums.length - 1; + while (true) { + int pos = partition(nums, left, right); + if (pos == k - 1) return nums[pos]; + else if (pos > k - 1) right = pos - 1; + else left = pos + 1; + } + } + + private int partition(int[] nums, int left, int right) { + int pivot = nums[left], l = left + 1, r = right; + while (l <= r) { + if (nums[l] < pivot && nums[r] > pivot) { + swap(nums, l++, r--); + } + if (nums[l] >= pivot) ++l; + if (nums[r] <= pivot) --r; + } + swap(nums, left, r); + return r; + } + + private void swap(int[] a, int i, int j) { + int tmp = a[i]; + a[i] = a[j]; + a[j] = tmp; + } + + + } + + public class UnitTest { + + + + } + +} diff --git a/src/main/java/kth_smallest_in_bst/KthSmallestInBst.java b/src/main/java/kth_smallest_in_bst/KthSmallestInBst.java new file mode 100644 index 0000000..d253939 --- /dev/null +++ b/src/main/java/kth_smallest_in_bst/KthSmallestInBst.java @@ -0,0 +1,49 @@ +package kth_smallest_in_bst; + +import common.TreeNode; + +import java.util.Stack; + +/** + * Created by lxie on 3/2/18. + */ +public class KthSmallestInBst { + + public class Solution { + public int kthSmallest(TreeNode root, int k) { + int[] c = {k}; + return kthSmallestDFS(root, c); + } + + private int kthSmallestDFS(TreeNode root, int[] c) { + if (root == null) return -1; + int val = kthSmallestDFS(root.left, c); + if (c[0] == 0) return val; + if (--c[0] == 0) return root.val; + return kthSmallestDFS(root.right, c); + } + + // non-recursive + public int kthSmallest2(TreeNode root, int k) { + int cnt = 0; + Stack s = new Stack<>(); + TreeNode p = root; + while (p != null || !s.empty()) { + while (p != null) { + s.push(p); + p = p.left; + } + p = s.peek(); s.pop(); + ++cnt; + if (cnt == k) return p.val; + p = p.right; + } + return 0; + } + } + + public static class UnitTest { + + } + +} diff --git a/src/main/java/kth_smallest_in_multi_table/KthSmallestInMultiTable.java b/src/main/java/kth_smallest_in_multi_table/KthSmallestInMultiTable.java new file mode 100644 index 0000000..7fd482a --- /dev/null +++ b/src/main/java/kth_smallest_in_multi_table/KthSmallestInMultiTable.java @@ -0,0 +1,33 @@ +package kth_smallest_in_multi_table; + +/** + * Created by lxie on 9/16/18. + */ +public class KthSmallestInMultiTable { + + public class Solution { + + public int findKthNumber(int m, int n, int k) { + int left = 1, right = m * n; + while (left < right) { + int mid = left + (right - left) / 2, cnt = 0, i = m, j = 1; + while (i >= 1 && j <= n) { + if (i * j <= mid) { + cnt += i; + ++j; + } else { + --i; + } + } + if (cnt < k) left = mid + 1; + else right = mid; + } + return right; + } + } + + public class UnitTest { + + + } +} diff --git a/src/main/java/kth_smallest_in_sorted_matrix/kthSmallestSortMatrix.java b/src/main/java/kth_smallest_in_sorted_matrix/kthSmallestSortMatrix.java new file mode 100644 index 0000000..c55a0b9 --- /dev/null +++ b/src/main/java/kth_smallest_in_sorted_matrix/kthSmallestSortMatrix.java @@ -0,0 +1,41 @@ +package kth_smallest_in_sorted_matrix; + +/** + * Created by lxie on 11/3/17. + */ +public class kthSmallestSortMatrix { + + public class Solution { + + public int kthSmallest(int[][] matrix, int k) { + int n = matrix.length; + int left = matrix[0][0], right = matrix[n-1][n-1]; + while (left < right) { + int mid = left + (right - left) / 2; + int cnt = search_less_equal(matrix, mid); + if (cnt < k) left = mid + 1; + else right = mid; + } + return left; + } + + public int search_less_equal(int[][] matrix, int target) { + int n = matrix.length, i = n - 1, j = 0, res = 0; + while (i >= 0 && j < n) { + if (matrix[i][j] <= target) { + res += i + 1; + ++j; + } else { + --i; + } + } + return res; + } + + } + + public static class UnitTest { + + } + +} diff --git a/src/main/java/largest_bst_subtree/LargestBSTSubtree.java b/src/main/java/largest_bst_subtree/LargestBSTSubtree.java new file mode 100644 index 0000000..c998183 --- /dev/null +++ b/src/main/java/largest_bst_subtree/LargestBSTSubtree.java @@ -0,0 +1,54 @@ +package largest_bst_subtree; + +import common.TreeNode; + +/** + * Created by lxie on 11/26/17. + */ +public class LargestBSTSubtree { + public static class Solution { + public int largest(TreeNode root) { + int[] params = new int[3]; + params[0] = Integer.MIN_VALUE; params[1] = Integer.MAX_VALUE; params[2] = 0; // mn, mx, res + boolean d = isValidBST(root, params); + return params[2]; + } + + boolean isValidBST(TreeNode root, int[] params) { + if (root == null) return true; + + int[] leftParams = new int[3]; + leftParams[0] = Integer.MIN_VALUE; leftParams[1] = Integer.MAX_VALUE; leftParams[2] = 0; + boolean left = isValidBST(root.left, leftParams); + int[] rightParams = new int[3]; + rightParams[0] = Integer.MIN_VALUE; rightParams[1] = Integer.MAX_VALUE; rightParams[2] = 0; + boolean right = isValidBST(root.right, rightParams); + + if (left && right) { + if ((root.left == null || root.val >= leftParams[1]) && (root.right == null || root.val <= rightParams[0])) { + params[2] = leftParams[2] + rightParams[2] + 1; + params[0] = root.left != null ? leftParams[0] : root.val; // update ranges + params[1] = root.right != null ? rightParams[1] : root.val; + return true; + } + } + params[2] = Integer.max(leftParams[2], rightParams[2]); + return false; + } + + + } + + public static void main(String[] args) { + Solution sol = new Solution(); + + TreeNode root = new TreeNode(10); + root.left = new TreeNode(5); root.right = new TreeNode(15); + root.left.left = new TreeNode(1); root.left.right = new TreeNode(8); + root.right.right = new TreeNode(7); + + int res = sol.largest(root); + + System.out.println("result is " + res); + } +} diff --git a/src/main/java/largest_divisible_subset/LargestDivisibleSubset.java b/src/main/java/largest_divisible_subset/LargestDivisibleSubset.java new file mode 100644 index 0000000..84f142f --- /dev/null +++ b/src/main/java/largest_divisible_subset/LargestDivisibleSubset.java @@ -0,0 +1,44 @@ +package largest_divisible_subset; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * Created by lxie on 11/6/17. + */ +public class LargestDivisibleSubset { + + public class Solution { + + public List largestDivisibleSubset(int[] nums) { + Arrays.sort(nums); + List res = new ArrayList<>(); + int[] dp = new int[nums.length]; + int[] parent = new int[nums.length]; + int mx = 0, mx_idx = 0; + for (int i = nums.length - 1; i >= 0; --i) { + for (int j = i; j < nums.length; ++j) { + if (nums[j] % nums[i] == 0 && dp[i] < dp[j] + 1) { + dp[i] = dp[j] + 1; + parent[i] = j; + if (mx < dp[i]) { + mx = dp[i]; + mx_idx = i; + } + } + } + } + for (int i = 0; i < mx; ++i) { + res.add(nums[mx_idx]); + mx_idx = parent[mx_idx]; // a good way to track + } + return res; + } + } + + public static class UnitTest { + + } + +} diff --git a/src/main/java/largest_number/LargestNumber.java b/src/main/java/largest_number/LargestNumber.java new file mode 100644 index 0000000..34eb1b0 --- /dev/null +++ b/src/main/java/largest_number/LargestNumber.java @@ -0,0 +1,53 @@ +package largest_number; + +import java.util.Arrays; +import java.util.Comparator; + +public class LargestNumber { + + public class Solution { + + private int skipLendingZeros(String s) { + int i = 0; + for (; i < s.length(); i++) { + if (s.charAt(i) != '0') { + return i; + } + } + return i; + } + + public String largestNumber(int[] num) { + String[] nums = new String[num.length]; + for (int i = 0; i < nums.length; i++) { + nums[i] = Integer.toString(num[i]); + } + Arrays.sort(nums, new Comparator() { + @Override + public int compare(String s1, String s2) { + return -(s1 + s2).compareTo(s2 + s1); + } + }); + StringBuilder builder = new StringBuilder(); + boolean skip = true; + for (String n : nums) { + if (skip) { + int start = skipLendingZeros(n); + if (start != n.length()) { + skip = false; + builder.append(n, start, n.length()); + } + } else { + builder.append(n); + } + } + String r = builder.toString(); + return r.isEmpty() ? "0" : r; + } + } + + public static class UnitTest { + + } +} + diff --git a/src/main/java/largest_rectangle_in_histogram/LargestRectangleinHistogram.java b/src/main/java/largest_rectangle_in_histogram/LargestRectangleinHistogram.java new file mode 100644 index 0000000..538c532 --- /dev/null +++ b/src/main/java/largest_rectangle_in_histogram/LargestRectangleinHistogram.java @@ -0,0 +1,31 @@ +package largest_rectangle_in_histogram; + +import java.util.Arrays; +import java.util.List; +import java.util.Stack; +import java.util.stream.Collectors; + +public class LargestRectangleinHistogram { + + public class Solution { + public int largestRectangleArea(int[] height) { + int res = 0; + List heights = Arrays.stream(height).boxed().collect(Collectors.toList());; + heights.add(0); + Stack st = new Stack<>(); + for (int i = 0; i < heights.size(); ++i) { + if (st.empty() || heights.get(st.peek()) < heights.get(i)) { + st.push(i); + } else { + int cur = st.peek(); st.pop(); + res = Math.max(res, heights.get(cur) * (st.empty() ? i : (i - st.peek() - 1))); + --i; + } + } + return res; + } + } + + public static class UnitTest { + } +} diff --git a/src/main/java/length_of_last_word/LengthofLastWord.java b/src/main/java/length_of_last_word/LengthofLastWord.java index 9e2fcd8..5d51395 100644 --- a/src/main/java/length_of_last_word/LengthofLastWord.java +++ b/src/main/java/length_of_last_word/LengthofLastWord.java @@ -4,23 +4,17 @@ public class LengthofLastWord { public class Solution { public int lengthOfLastWord(String s) { + int i = s.length() - 1; + while (i >= 0 && s.charAt(i) == ' ') { + i--; + } + if (i < 0) { + return 0; + } int len = 0; - int i = 0; - while (true) { - while (i < s.length() && s.charAt(i) == ' ') { - i++; - } - if (i == s.length()) { - break; - } - int start = i; - while (i < s.length() && s.charAt(i) != ' ') { - i++; - } - len = i - start; - if (i == s.length()) { - break; - } + while (i >= 0 && s.charAt(i) != ' ') { + len++; + i--; } return len; } diff --git a/src/main/java/letter_combinations_of_a_phone_number/LetterCombinationsofaPhoneNumber.java b/src/main/java/letter_combinations_of_a_phone_number/LetterCombinationsofaPhoneNumber.java index efb05d8..693838b 100644 --- a/src/main/java/letter_combinations_of_a_phone_number/LetterCombinationsofaPhoneNumber.java +++ b/src/main/java/letter_combinations_of_a_phone_number/LetterCombinationsofaPhoneNumber.java @@ -1,6 +1,7 @@ package letter_combinations_of_a_phone_number; import java.util.ArrayList; +import java.util.List; public class LetterCombinationsofaPhoneNumber { @@ -18,26 +19,23 @@ public class Solution { "wxyz" // 9 }; - private void search(ArrayList ans, String digits, int index, - char[] letters) { - if (index == digits.length()) { - ans.add(new String(letters)); - return; - } + public List letterCombinations(String digits) { + List res = new ArrayList<>(); + if (digits.isEmpty()) return res; + letterCombinationsDFS(digits, dict, 0, "", res); + return res; + } - String options = dict[digits.charAt(index) - '0']; - for (int i = 0; i < options.length(); i++) { - letters[index] = options.charAt(i); - search(ans, digits, index + 1, letters); + private void letterCombinationsDFS(String digits, String[] dict, int level, String out, List res) { + if (level == digits.length()) res.add(out); + else { + String str = dict[digits.charAt(level) - '0']; + for (int i = 0; i < str.length(); ++i) { + letterCombinationsDFS(digits, dict, level + 1, out + str.charAt(i), res); + } } } - public ArrayList letterCombinations(String digits) { - ArrayList ans = new ArrayList(); - char[] letters = new char[digits.length()]; - search(ans, digits, 0, letters); - return ans; - } } public static class UnitTest { diff --git a/src/main/java/license_key_formatting/LicenseKeyFormatting.java b/src/main/java/license_key_formatting/LicenseKeyFormatting.java new file mode 100644 index 0000000..296f81a --- /dev/null +++ b/src/main/java/license_key_formatting/LicenseKeyFormatting.java @@ -0,0 +1,25 @@ +package license_key_formatting; + +/** + * Created by lxie on 8/19/18. + */ +public class LicenseKeyFormatting { + + public class Solution { + public String licenseKeyFormatting(String S, int K) { + StringBuilder res = new StringBuilder(); + for (int i = (int)S.length() - 1; i >= 0; --i) { + if (S.charAt(i) != '-') { + ((res.length() % (K + 1) - K) != 0? res : res.append('-')). + append(Character.toUpperCase(S.charAt(i))); + } + } + return res.reverse().toString(); + } + } + + public class UnitTest { + + + } +} diff --git a/src/main/java/line_reflection/LineReflection.java b/src/main/java/line_reflection/LineReflection.java new file mode 100644 index 0000000..1f935df --- /dev/null +++ b/src/main/java/line_reflection/LineReflection.java @@ -0,0 +1,39 @@ +package line_reflection; + +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +/** + * Created by lxie on 1/24/18. + */ +public class LineReflection { + + public class Solution { + public boolean isReflected(int[][] points) { + Map> m = new HashMap<>(); + int mx = Integer.MIN_VALUE, mn = Integer.MIN_VALUE; + for (int[] a : points) { + mx = Integer.max(mx, a[0]); + mn = Integer.min(mn, a[0]); + m.get(a[0]).add(a[1]); + } + double y = (double)(mx + mn) / 2; + for (int[] a : points) { + double t = 2 * y - a[0]; + if (!m.containsKey(t) || !m.get(t).contains(a[1])) { + return false; + } + } + return true; + } + } + + public static class UnitTest { + + + + } + + +} diff --git a/src/main/java/linked_list_cycle_ii/LinkedListCycleII.java b/src/main/java/linked_list_cycle_ii/LinkedListCycleII.java new file mode 100644 index 0000000..2b156ce --- /dev/null +++ b/src/main/java/linked_list_cycle_ii/LinkedListCycleII.java @@ -0,0 +1,29 @@ +package linked_list_cycle_ii; + +import common.ListNode; + +public class LinkedListCycleII { + + public class Solution { + public ListNode detectCycle(ListNode head) { + ListNode fast = head; + ListNode slow = head; + while (fast != null && fast.next != null) { + fast = fast.next.next; + slow = slow.next; + if (fast == slow) { + while (fast != head) { + fast = fast.next; + head = head.next; + } + return fast; + } + } + return null; + } + } + + public static class UnitTest { + + } +} diff --git a/src/main/java/linked_list_random_node/LinkedListRandomNode.java b/src/main/java/linked_list_random_node/LinkedListRandomNode.java new file mode 100644 index 0000000..570d0e4 --- /dev/null +++ b/src/main/java/linked_list_random_node/LinkedListRandomNode.java @@ -0,0 +1,37 @@ +package linked_list_random_node; + +import common.ListNode; + +import java.util.Random; + +/** + * Created by lxie on 9/2/18. + */ +public class LinkedListRandomNode { + + public class Solution { + + private ListNode head = null; + + public Solution(ListNode head) { + this.head = head; + } + + public int getRandom() { + int res = head.val, i = 2; + ListNode cur = head.next; + Random generator = new Random(); + while (cur != null) { + int j = generator.nextInt(i); // reservior sampling size = 1 + if (j == 0) res = cur.val; + ++i; + cur = cur.next; + } + return res; + } + } + + public class UnitTest { + + } +} diff --git a/src/main/java/logger_rate_limiter/Logger.java b/src/main/java/logger_rate_limiter/Logger.java new file mode 100644 index 0000000..f07d5bd --- /dev/null +++ b/src/main/java/logger_rate_limiter/Logger.java @@ -0,0 +1,26 @@ +package logger_rate_limiter; + +import java.util.HashMap; +import java.util.Map; + +/** + * Created by lxie on 7/4/18. + */ +public class Logger { + + public Logger() {}; + + private Map m = new HashMap<>(); + + boolean shouldPrintMessage(int timestamp, String message) { + if (!m.containsKey(message)) { + m.put(message, timestamp); + return true; + } + if (timestamp - m.get(message) >= 10) { + m.put(message, timestamp); + return true; + } + return false; + } +} diff --git a/src/main/java/lonely_pixel/LonelyPixel.java b/src/main/java/lonely_pixel/LonelyPixel.java new file mode 100644 index 0000000..2f8ac83 --- /dev/null +++ b/src/main/java/lonely_pixel/LonelyPixel.java @@ -0,0 +1,42 @@ +package lonely_pixel; + +/** + * Created by lxie on 9/17/18. + */ +public class LonelyPixel { + + public class Solution { + + public int findLonelyPixel(char[][] picture) { + if (picture.length == 0 || picture[0].length == 0) return 0; + int m = picture.length, n = picture[0].length, res = 0; + int[] rowCnt = new int[m]; + int[] colCnt = new int[n]; + for (int i = 0; i < m; ++i) { + for (int j = 0; j < n; ++j) { + if (picture[i][j] == 'B') { + ++rowCnt[i]; + ++colCnt[j]; + } + } + } + for (int i = 0; i < m; ++i) { + for (int j = 0; j < n; ++j) { + if (picture[i][j] == 'B') { + if (rowCnt[i] == 1 && colCnt[j] == 1) { + ++res; + } + } + } + } + return res; + } + + } + + public class UnitTest { + + + } + +} diff --git a/src/main/java/lonely_pixel_ii/LonelyPixelII.java b/src/main/java/lonely_pixel_ii/LonelyPixelII.java new file mode 100644 index 0000000..f0d73c2 --- /dev/null +++ b/src/main/java/lonely_pixel_ii/LonelyPixelII.java @@ -0,0 +1,49 @@ +package lonely_pixel_ii; + +import java.util.HashMap; +import java.util.Map; + +/** + * Created by lxie on 9/17/18. + */ +public class LonelyPixelII { + + public class Solution { + + public int findBlackPixel(char[][] picture, int N) { + if (picture.length != 0 || picture[0].length != 0) return 0; + int m = picture.length, n = picture[0].length, res = 0; + int[] colCnt = new int[n]; + Map u = new HashMap<>(); + for (int i = 0; i < m; ++i) { + int cnt = 0; + for (int j = 0; j < n; ++j) { + if (picture[i][j] == 'B') { + ++colCnt[j]; + ++cnt; + } + } + if (cnt == N) { + String line = new String(picture[i]); + if (u.containsKey(line)) { + u.put(line, u.get(line)+1); + } else { + u.put(line, 1); + } + } + } + for (Map.Entry a : u.entrySet()) { + if (a.getValue() != N) continue; + for (int i = 0; i < n; ++i) { + res += (a.getKey().charAt(i) == 'B' && colCnt[i] == N) ? N : 0; + } + } + return res; + } + + } + + public class UnitTest { + + } +} diff --git a/src/main/java/longest_absolute_file_path/LongAbsoluteFilePath.java b/src/main/java/longest_absolute_file_path/LongAbsoluteFilePath.java new file mode 100644 index 0000000..167b6a1 --- /dev/null +++ b/src/main/java/longest_absolute_file_path/LongAbsoluteFilePath.java @@ -0,0 +1,33 @@ +package longest_absolute_file_path; + +import java.util.HashMap; +import java.util.Map; + +/** + * Created by lxie on 9/19/17. + */ +public class LongAbsoluteFilePath { + + class Solution { + public int lengthLongestPath(String input) { + int res = 0; + Map m = new HashMap<>(); + m.put(0, 0); + for (String s : input.split("\n")) { + int level = s.lastIndexOf("\t") + 1; + int len = s.substring(level).length(); + if (s.contains(".")) { + res = Math.max(res, m.get(level) + len); + } else { + m.put(level + 1, m.get(level) + len + 1); + } + } + return res; + + } + } + + public static void main(String[] args) { + System.out.println("this is for test"); + } +} diff --git a/src/main/java/longest_common_prefix/LongestCommonPrefix.java b/src/main/java/longest_common_prefix/LongestCommonPrefix.java new file mode 100644 index 0000000..87b8022 --- /dev/null +++ b/src/main/java/longest_common_prefix/LongestCommonPrefix.java @@ -0,0 +1,26 @@ +package longest_common_prefix; + +public class LongestCommonPrefix { + + public class Solution { + public String longestCommonPrefix(String[] strs) { + if (strs.length == 0) return ""; + String res = ""; + for (int j = 0; j < strs[0].length(); ++j) { + char c = strs[0].charAt(j); + for (int i = 1; i < strs.length; ++i) { + if (j >= strs[i].length() || strs[i].charAt(j) != c) { + return res; + } + } + res += c; + } + return res; + } + + } + + public static class UnitTest { + + } +} diff --git a/src/main/java/longest_consecutive_sequence/LongestConsecutiveSequence.java b/src/main/java/longest_consecutive_sequence/LongestConsecutiveSequence.java index 0e068f6..1b0af5e 100644 --- a/src/main/java/longest_consecutive_sequence/LongestConsecutiveSequence.java +++ b/src/main/java/longest_consecutive_sequence/LongestConsecutiveSequence.java @@ -1,30 +1,26 @@ package longest_consecutive_sequence; -import java.util.HashSet; +import java.util.HashMap; +import java.util.Map; public class LongestConsecutiveSequence { public class Solution { - public int longestConsecutive(int[] num) { - HashSet nums = new HashSet(); - for (int n : num) { - nums.add(n); - } - int ans = 0; - for (int n : num) { - int i = n - 1; - while (nums.contains(i)) { - nums.remove(i); - i--; - } - int j = n + 1; - while (nums.contains(j)) { - nums.remove(j); - j++; + public int longestConsecutive(int[] nums) { + int res = 0; + Map m = new HashMap<>(); + for (int d : nums) { + if (!m.containsKey(d)) { + int left = m.containsKey(d - 1) ? m.get(d - 1) : 0; + int right = m.containsKey(d + 1) ? m.get(d + 1) : 0; + int sum = left + right + 1; + m.put(d, sum); + res = Math.max(res, sum); + m.put(d - left, sum); + m.put(d + right, sum); } - ans = Math.max(ans, j - i - 1); } - return ans; + return res; } } diff --git a/src/main/java/longest_increasing_path_in_matrix/LongestIncreasingPathMatrix.java b/src/main/java/longest_increasing_path_in_matrix/LongestIncreasingPathMatrix.java new file mode 100644 index 0000000..da2034a --- /dev/null +++ b/src/main/java/longest_increasing_path_in_matrix/LongestIncreasingPathMatrix.java @@ -0,0 +1,47 @@ +package longest_increasing_path_in_matrix; + +/** + * Created by lxie on 1/23/18. + */ +public class LongestIncreasingPathMatrix { + + public class Solution { + + public final int[][] dirs = new int[][] {{0, -1}, {-1, 0}, {0, 1}, {1, 0}}; + + + public int longestIncreasingPath(int[][] matrix) { + if (matrix.length == 0 || matrix[0].length == 0) return 0; + int res = 1, m = matrix.length, n = matrix[0].length; + int[][] dp = new int[m][n]; + + for (int i = 0; i < m; ++i) { + for (int j = 0; j < n; ++j) { + res = Integer.max(res, dfs(matrix, dp, i, j)); + } + } + return res; + } + + + private int dfs(int[][] matrix, int[][] dp, int i, int j) { + if (dp[i][j] != 0) return dp[i][j]; + int mx = 1, m = matrix.length, n = matrix[0].length; + for (int[] a : dirs) { + int x = i + a[0], y = j + a[1]; + if (x < 0 || x >= m || y < 0 || y >= n || matrix[x][y] <= matrix[i][j]) continue; + int len = 1 + dfs(matrix, dp, x, y); + mx = Integer.max(mx, len); + } + dp[i][j] = mx; + return mx; + } + + } + + public static class UnitTest { + + + + } +} diff --git a/src/main/java/longest_increasing_subsequence/LongestIncSubsequence.java b/src/main/java/longest_increasing_subsequence/LongestIncSubsequence.java new file mode 100644 index 0000000..66279f1 --- /dev/null +++ b/src/main/java/longest_increasing_subsequence/LongestIncSubsequence.java @@ -0,0 +1,55 @@ +package longest_increasing_subsequence; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by lxie on 6/22/18. + */ +public class LongestIncSubsequence { + + public class Solution { + + // O(n^2) + public int lengthOfLIS(int[] nums) { + int[] dp = new int[nums.length]; + for (int i=0; i nums[j]) { + dp[i] = Math.max(dp[i], dp[j] + 1); + } + } + res = Math.max(res, dp[i]); + } + return res; + } + + // O(nlogn) + public int lengthOfLIS1(int[] nums) { + if (nums.length == 0) return 0; + List ends = new ArrayList<>(); + ends.add(nums[0]); + for (int a : nums) { + if (a < ends.get(0)) ends.set(0, a); + else if (a > ends.get(ends.size()-1)) ends.add(a); + else { + int left = 0, right = ends.size(); + while (left < right) { + int mid = left + (right - left) / 2; + if (ends.get(mid) < a) left = mid + 1; + else right = mid; + } + ends.set(right, a); // find first >= a and replace it + } + } + return ends.size(); + } + + } + + public class UnitTest { + + } +} diff --git a/src/main/java/longest_line_consecutive_one_in_matrix/LongestLineConsecutiveOneInMatrix.java b/src/main/java/longest_line_consecutive_one_in_matrix/LongestLineConsecutiveOneInMatrix.java new file mode 100644 index 0000000..c922968 --- /dev/null +++ b/src/main/java/longest_line_consecutive_one_in_matrix/LongestLineConsecutiveOneInMatrix.java @@ -0,0 +1,37 @@ +package longest_line_consecutive_one_in_matrix; + +import static java.lang.Math.max; + +/** + * Created by lxie on 9/14/18. + */ +public class LongestLineConsecutiveOneInMatrix { + + public class Solution { + + public int longestLine(int[][] M) { + if (M.length == 0 || M[0].length == 0) return 0; + int m = M.length, n = M[0].length, res = 0; + int[][][] dp = new int[m][n][4]; + for (int i = 0; i < m; ++i) { + for (int j = 0; j < n; ++j) { + if (M[i][j] == 0) continue; + for (int k = 0; k < 4; ++k) dp[i][j][k] = 1; + if (j > 0) dp[i][j][0] += dp[i][j - 1][0]; // horizonal + if (i > 0) dp[i][j][1] += dp[i - 1][j][1]; // vertical + if (i > 0 && j < n - 1) dp[i][j][2] += dp[i - 1][j + 1][2]; // diagonal + if (i > 0 && j > 0) dp[i][j][3] += dp[i - 1][j - 1][3]; // anti-diagonal + res = max(res, max(dp[i][j][0], dp[i][j][1])); + res = max(res, max(dp[i][j][2], dp[i][j][3])); + } + } + return res; + } + } + + public class UnitTest { + + + } + +} diff --git a/src/main/java/longest_palindrome/LongestPalindrome.java b/src/main/java/longest_palindrome/LongestPalindrome.java new file mode 100644 index 0000000..b5f3cb9 --- /dev/null +++ b/src/main/java/longest_palindrome/LongestPalindrome.java @@ -0,0 +1,38 @@ +package longest_palindrome; + +import java.util.HashMap; +import java.util.Map; + +/** + * Created by lxie on 7/13/18. + */ +public class LongestPalindrome { + + public class Solution { + int longestPalindrome(String s) { + int res = 0; + boolean mid = false; + Map m = new HashMap<>(); + for (char c : s.toCharArray()) { + if (!m.containsKey(c)) { + m.put(c, 1); + } else { + m.put(c, m.get(c) + 1); + } + }; + + for (Map.Entry it: m.entrySet()) { + res += it.getValue(); + if (it.getValue() % 2 == 1) { + res -= 1; + mid = true; + } + } + return mid ? res + 1 : res; + } + } + + public class UnitTest { + + } +} diff --git a/src/main/java/longest_palindromic_subsequence/LongestPalindromeSubsequence.java b/src/main/java/longest_palindromic_subsequence/LongestPalindromeSubsequence.java new file mode 100644 index 0000000..2ba5adc --- /dev/null +++ b/src/main/java/longest_palindromic_subsequence/LongestPalindromeSubsequence.java @@ -0,0 +1,30 @@ +package longest_palindromic_subsequence; + +/** + * Created by lxie on 8/18/18. + */ +public class LongestPalindromeSubsequence { + + public class Solution { + public int longestPalindromeSubseq(String s) { + int n = s.length(); + int[][] dp = new int[n][n]; + for (int i = n - 1; i >= 0; --i) { + dp[i][i] = 1; + for (int j = i + 1; j < n; ++j) { + if (s.charAt(i) == s.charAt(j)) { + dp[i][j] = dp[i + 1][j - 1] + 2; + } else { + dp[i][j] = Math.max(dp[i + 1][j], dp[i][j - 1]); + } + } + } + return dp[0][n - 1]; + } + } + + public class UnitTest { + + } + +} diff --git a/src/main/java/longest_palindromic_substring/LongestPalindromicSubstring.java b/src/main/java/longest_palindromic_substring/LongestPalindromicSubstring.java index 3965af0..e75d33f 100644 --- a/src/main/java/longest_palindromic_substring/LongestPalindromicSubstring.java +++ b/src/main/java/longest_palindromic_substring/LongestPalindromicSubstring.java @@ -1,50 +1,30 @@ package longest_palindromic_substring; -import static org.junit.Assert.assertEquals; - import org.junit.Test; +import static org.junit.Assert.assertEquals; + public class LongestPalindromicSubstring { public class Solution { public String longestPalindrome(String s) { - String t = "^#"; - for (int i = 0; i < s.length(); i++) { - t += s.charAt(i); - t += '#'; - } - t += '$'; - - int[] p = new int[t.length()]; - int id = 1; - p[1] = 1; - int rightIndex = 2; - for (int i = 2; i < t.length() - 1; i++) { - if (rightIndex > i) { - p[i] = Math.min(p[2 * id - i], rightIndex - i); - } else { - p[i] = 1; - } - while (t.charAt(i + p[i]) == t.charAt(i - p[i])) { - p[i]++; - } - if (rightIndex < i + p[i]) { - rightIndex = i; - id = i; - } - } - - int maxId = 1; - for (int i = 2; i < t.length() - 1; i++) { - if (p[maxId] < p[i]) { - maxId = i; + // DP dp[i][j] - if substr(i,j) is palindrome + boolean [][] dp = new boolean[s.length()][s.length()]; + int left = 0, right = 0, len = 0; + for (int i = 0; i < s.length(); ++i) { + for (int j = 0; j < i; ++j) { + dp[j][i] = (s.charAt(i) == s.charAt(j) && (i - j < 2 || dp[j + 1][i - 1] == true)); + if (dp[j][i] && len < i - j + 1) { + len = i - j + 1; + left = j; + right = i; + } } + dp[i][i] = true; } - - int length = p[maxId] - 1; - int startIndex = (maxId - p[maxId]) / 2; - return s.substring(startIndex, startIndex + length); + return s.substring(left, right + 1); } + } public static class UnitTest { diff --git a/src/main/java/longest_substr_at_most_two_distinct_chars/LongestStrTwoDistinct.java b/src/main/java/longest_substr_at_most_two_distinct_chars/LongestStrTwoDistinct.java new file mode 100644 index 0000000..abfee10 --- /dev/null +++ b/src/main/java/longest_substr_at_most_two_distinct_chars/LongestStrTwoDistinct.java @@ -0,0 +1,43 @@ +package longest_substr_at_most_two_distinct_chars; + +import java.util.HashMap; +import java.util.Map; + +/** + * Created by lxie on 2/1/18. + */ +public class LongestStrTwoDistinct { + + public static class Solution { + + public int lengthOfLongestSubstringTwoDistinct(String s) { + int res = 0, left = 0; + Map m = new HashMap<>(); + char[] s1 = s.toCharArray(); + + for (int i = 0; i < s.length(); ++i) { + if (!m.containsKey(s1[i])) { + m.put(s1[i], 1); + } else { + m.put(s1[i], m.get(s1[i])+1); + } + + while (m.size() > 2) { + m.put(s1[left], m.get(s1[left])-1); + if (m.get(s1[left]) == 0) m.remove(s1[left]); + ++left; + } + res = Integer.max(res, i - left + 1); + } + return res; + } + } + + public static void main(String[] args) { + System.out.println("this is for test"); + Solution sol = new Solution(); + int res = sol.lengthOfLongestSubstringTwoDistinct("eceba"); + System.out.println(res); + } + +} diff --git a/src/main/java/longest_substring_k_repeating_chars/LongestSubstringKRepeatingChars.java b/src/main/java/longest_substring_k_repeating_chars/LongestSubstringKRepeatingChars.java new file mode 100644 index 0000000..cce1e67 --- /dev/null +++ b/src/main/java/longest_substring_k_repeating_chars/LongestSubstringKRepeatingChars.java @@ -0,0 +1,41 @@ +package longest_substring_k_repeating_chars; + +import java.util.Arrays; + + +/** + * Created by lxie on 9/9/17. + */ +public class LongestSubstringKRepeatingChars { + + public static class Solution { + public int longestSubstring(String s, int k) { + int res = 0, i = 0, n = s.length(); + while (i + k <= n) { + int[] m = new int[26]; + Arrays.fill(m, 0); + int mask = 0, max_idx = i; + for (int j = i; j < n; ++j) { + int t = s.charAt(j) - 'a'; + ++m[t]; + if (m[t] < k) mask |= (1 << t); + else mask &= (~(1 << t)); + if (mask == 0) { // existing ones all >= k + res = Math.max(res, j - i + 1); + max_idx = j; + } + + } + i = max_idx + 1; + } + return res; + } + } + + + public static void main(String[] args) { + Solution sol = new Solution(); + System.out.println("result = " + sol.longestSubstring("ababbc", 2)); + } + +} diff --git a/src/main/java/longest_substring_most_k_distinct/LongestSubstringKMost.java b/src/main/java/longest_substring_most_k_distinct/LongestSubstringKMost.java new file mode 100644 index 0000000..2baa60a --- /dev/null +++ b/src/main/java/longest_substring_most_k_distinct/LongestSubstringKMost.java @@ -0,0 +1,38 @@ +package longest_substring_most_k_distinct; + +import java.util.HashMap; +import java.util.Map; + +import static java.lang.Math.max; + +/** + * Created by lxie on 12/2/17. + */ +public class LongestSubstringKMost { + public static class Solution { + private int LongestSubstringKMost(String s, int k) { + int res = 0, left = 0; + Map m = new HashMap<>(); + for (int i = 0; i < s.length(); ++i) { + if (!m.containsKey(s.charAt(i))) m.put(s.charAt(i), 1); + else + m.put(s.charAt(i), m.get(s.charAt(i))+1); + while (m.size() > k) { + if (m.get(s.charAt(left)) == 1) m.remove(s.charAt(left)); + else + m.put(s.charAt(left), m.get(s.charAt(left))-1); + ++left; + } + res = max(res, i - left + 1); + } + return res; + + } + + } + + public static void main(String[] args) { + Solution sol = new Solution(); + System.out.println("result = " + sol.LongestSubstringKMost("eceba", 2)); + } +} diff --git a/src/main/java/longest_substring_without_repeating_characters/LongestSubstringWithoutRepeatingCharacters.java b/src/main/java/longest_substring_without_repeating_characters/LongestSubstringWithoutRepeatingCharacters.java index f31e15c..690c921 100644 --- a/src/main/java/longest_substring_without_repeating_characters/LongestSubstringWithoutRepeatingCharacters.java +++ b/src/main/java/longest_substring_without_repeating_characters/LongestSubstringWithoutRepeatingCharacters.java @@ -6,18 +6,14 @@ public class LongestSubstringWithoutRepeatingCharacters { public class Solution { public int lengthOfLongestSubstring(String s) { - int[] prevPos = new int[Character.MAX_VALUE + 1]; - Arrays.fill(prevPos, -1); - int substringBegin = 0; - int maxSubstringLen = 0; - for (int i = 0; i < s.length(); i++) { - substringBegin = Math.max(substringBegin, - prevPos[s.charAt(i)] + 1); - prevPos[s.charAt(i)] = i; - maxSubstringLen = Math.max(maxSubstringLen, i - substringBegin - + 1); + int[] m = new int[256]; Arrays.fill(m, -1); + int res = 0, left = -1; + for (int i = 0; i < s.length(); ++i) { + left = Math.max(left, m[s.charAt(i)]); + m[s.charAt(i)] = i; + res = Math.max(res, i - left); } - return maxSubstringLen; + return res; } } diff --git a/src/main/java/longest_uncommon_subsequence_ii/LongestUncommonSubsequence.java b/src/main/java/longest_uncommon_subsequence_ii/LongestUncommonSubsequence.java new file mode 100644 index 0000000..7c22714 --- /dev/null +++ b/src/main/java/longest_uncommon_subsequence_ii/LongestUncommonSubsequence.java @@ -0,0 +1,49 @@ +package longest_uncommon_subsequence_ii; + +import java.util.Arrays; +import java.util.Comparator; +import java.util.HashSet; +import java.util.Set; + +/** + * Created by lxie on 9/20/18. + */ +public class LongestUncommonSubsequence { + + public int findLUSlength(String[] strs) { + int n = strs.length; + Set s = new HashSet<>(); + Arrays.sort(strs, new Comparator() { + @Override + public int compare(String a, String b) { + if (a.length() == b.length()) return b.compareTo(a); + return b.length() - a.length(); + } + }); + for (int i = 0; i < n; ++i) { + if (i == n - 1 || strs[i] != strs[i + 1]) { + boolean found = true; + for (String a : s) { // compare to longer ones + int j = 0; + for (char c : a.toCharArray()) { + if (c == strs[i].charAt(j)) ++j; + if (j == strs[i].length()) break; + } + if (j == strs[i].length()) { + found = false; + break; + } + } + if (found) return strs[i].length(); + } + s.add(strs[i]); + } + return -1; + } + + public static void main(String[] args) { + LongestUncommonSubsequence s = new LongestUncommonSubsequence(); + String[] input = {"aba", "cdc", "eae", "whatsapp"}; + System.out.println(s.findLUSlength(input)); + } +} diff --git a/src/main/java/longest_univalue_path/LongestUnivaluePath.java b/src/main/java/longest_univalue_path/LongestUnivaluePath.java new file mode 100644 index 0000000..dad30e0 --- /dev/null +++ b/src/main/java/longest_univalue_path/LongestUnivaluePath.java @@ -0,0 +1,29 @@ +package longest_univalue_path; + +import common.TreeNode; + +/** + * Created by lxie on 7/18/18. + */ +public class LongestUnivaluePath { + + public class Solution { + + public int longestUnivaluePath(TreeNode root) { + if (root == null) return 0; + int sub = Math.max(longestUnivaluePath(root.left), longestUnivaluePath(root.right)); + return Math.max(sub, helper(root.left, root.val) + helper(root.right, root.val)); + } + + private int helper(TreeNode node, int parent) { + if (node == null || node.val != parent) return 0; + return 1 + Math.max(helper(node.left, node.val), helper(node.right, node.val)); + } + } + + public class UnitTest { + + + + } +} diff --git a/src/main/java/longest_valid_parentheses/LongestValidParentheses.java b/src/main/java/longest_valid_parentheses/LongestValidParentheses.java new file mode 100644 index 0000000..d8581fd --- /dev/null +++ b/src/main/java/longest_valid_parentheses/LongestValidParentheses.java @@ -0,0 +1,31 @@ +package longest_valid_parentheses; + +import java.util.Stack; + +import static java.lang.Math.max; + +public class LongestValidParentheses { + + public class Solution { + public int longestValidParentheses(String s) { + int res = 0, start = 0; + Stack m = new Stack<>(); + for (int i = 0; i < s.length(); ++i) { + if (s.charAt(i) == '(') m.push(i); + else if (s.charAt(i) == ')') { + if (m.empty()) start = i + 1; + else { + m.pop(); + res = m.empty() ? max(res, i - start + 1) : max(res, i - m.peek()); + } + } + } + return res; + } + + } + + public static class UnitTest { + + } +} diff --git a/src/main/java/longest_word_in_dict_through_deleting/LongestWordDeleting.java b/src/main/java/longest_word_in_dict_through_deleting/LongestWordDeleting.java new file mode 100644 index 0000000..5b9993b --- /dev/null +++ b/src/main/java/longest_word_in_dict_through_deleting/LongestWordDeleting.java @@ -0,0 +1,32 @@ +package longest_word_in_dict_through_deleting; + +import java.util.List; + +/** + * Created by lxie on 8/21/18. + */ +public class LongestWordDeleting { + + public class Solution { + public String findLongestWord(String s, List d) { + String res = ""; + for (String str : d) { + int i = 0; + for (char c : s.toCharArray()) { + if (i < str.length() && c == str.charAt(i)) ++i; + } + if (i == str.length() && str.length() >= res.length()) { + if (str.length() > res.length() || str.compareTo(res) < 0) { + res = str; + } + } + } + return res; + } + } + + public class UnitTest { + + + } +} diff --git a/src/main/java/lru_cache/LRUCache.java b/src/main/java/lru_cache/LRUCache.java new file mode 100644 index 0000000..30c8567 --- /dev/null +++ b/src/main/java/lru_cache/LRUCache.java @@ -0,0 +1,71 @@ +package lru_cache; + +import java.util.HashMap; + +public class LRUCache { + private class Node{ + Node prev; + Node next; + int key; + int value; + + public Node(int key, int value) { + this.key = key; + this.value = value; + this.prev = null; + this.next = null; + } + } + + private int capacity; + private HashMap hs = new HashMap(); + private Node head = new Node(-1, -1); + private Node tail = new Node(-1, -1); + + public LRUCache(int capacity) { + this.capacity = capacity; + tail.prev = head; + head.next = tail; + } + + public int get(int key) { + if( !hs.containsKey(key)) { + return -1; + } + + // remove current + Node current = hs.get(key); + current.prev.next = current.next; + current.next.prev = current.prev; + + // move current to tail + move_to_tail(current); + + return hs.get(key).value; + } + + public void put(int key, int value) { + // get 这个方法会把key挪到最末端,因此,不需要再调用 move_to_tail + if (get(key) != -1) { + hs.get(key).value = value; + return; + } + + if (hs.size() == capacity) { + hs.remove(head.next.key); + head.next = head.next.next; + head.next.prev = head; + } + + Node insert = new Node(key, value); + hs.put(key, insert); + move_to_tail(insert); + } + + private void move_to_tail(Node current) { + current.prev = tail.prev; + tail.prev = current; + current.prev.next = current; + current.next = tail; + } +} diff --git a/src/main/java/magic_string/MagicString.java b/src/main/java/magic_string/MagicString.java new file mode 100644 index 0000000..2001039 --- /dev/null +++ b/src/main/java/magic_string/MagicString.java @@ -0,0 +1,36 @@ +package magic_string; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * Created by lxie on 9/10/18. + */ +public class MagicString { + + public class Solution { + + public int magicalString(int n) { + if (n <= 0) return 0; + if (n <= 3) return 1; + int res = 1, head = 2, tail = 3, num = 1; + List v = new ArrayList<>(Arrays.asList(1, 2, 2)); + while (tail < n) { + for (int i = 0; i < v.get(head); ++i) { + v.add(num); + if (num == 1 && tail < n) ++res; + ++tail; + } + num ^= 3; + ++head; + } + return res; + } + + } + + public class UnitTest { + + } +} diff --git a/src/main/java/majority_element/MajorityElement.java b/src/main/java/majority_element/MajorityElement.java new file mode 100644 index 0000000..635ce5a --- /dev/null +++ b/src/main/java/majority_element/MajorityElement.java @@ -0,0 +1,29 @@ +package majority_element; + +public class MajorityElement { + + public class Solution { + public int majorityElement(int[] num) { + int majority = num[0]; + int count = 1; + for (int i = 1; i < num.length; i++) { + if (majority != num[i]) { + count--; + if (count == 0) { + // the majority element always exist in the array + majority = num[++i]; + count = 1; + } + } else { + count++; + } + } + return majority; + } + } + + public static class UnitTest { + + } +} + diff --git a/src/main/java/majority_element_ii/MajorityElementII.java b/src/main/java/majority_element_ii/MajorityElementII.java new file mode 100644 index 0000000..44e1566 --- /dev/null +++ b/src/main/java/majority_element_ii/MajorityElementII.java @@ -0,0 +1,37 @@ +package majority_element_ii; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by lxie on 2/28/18. + */ +public class MajorityElementII { + + public class Solution { + public List majorityElement(int[] nums) { + List res = new ArrayList<>(); + int m = 0, n = 0, cm = 0, cn = 0; + for (int a : nums) { // find two majority + if (a == m) ++cm; + else if (a ==n) ++cn; + else if (cm == 0) { m = a; cm = 1; } + else if (cn == 0) { n = a; cn = 1; } + else { --cm; --cn; } + } + cm = cn = 0; + for (int a : nums) { // verify if > n/3 + if (a == m) ++cm; + else if (a == n) ++cn; + } + if (cm > nums.length / 3) res.add(m); + if (cn > nums.length / 3) res.add(n); + return res; + + } + } + + public static class UnitTest { + + } +} diff --git a/src/main/java/max_avg_subarray_ii/MaxAvgSubarrayII.java b/src/main/java/max_avg_subarray_ii/MaxAvgSubarrayII.java new file mode 100644 index 0000000..5597086 --- /dev/null +++ b/src/main/java/max_avg_subarray_ii/MaxAvgSubarrayII.java @@ -0,0 +1,41 @@ +package max_avg_subarray_ii; + +import com.google.common.primitives.Doubles; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +/** + * Created by lxie on 9/22/18. + */ +public class MaxAvgSubarrayII { + + public double findMaxAverage(int[] nums, int k) { + List numsd = Doubles.asList(Arrays.stream(nums).asDoubleStream().toArray()); + double left = Collections.min(numsd); + double right = Collections.max(numsd); + while (right - left > 1e-5) { + double minSum = 0, sum = 0, preSum = 0, mid = left + (right - left) / 2; + boolean check = false; + for (int i = 0; i < nums.length; ++i) { + sum += nums[i] - mid; + if (i >= k) { + preSum += nums[i - k] - mid; + minSum = Math.min(minSum, preSum); + } + if (i >= k - 1 && sum > minSum) {check = true; break;} + } + if (check) left = mid; + else right = mid; + } + return left; + } + + public static void main(String[] args) { + MaxAvgSubarrayII m = new MaxAvgSubarrayII(); + int[] input = {1,12,-5,-6,50,3}; + System.out.println(m.findMaxAverage(input, 4)); + } + +} diff --git a/src/main/java/max_consecutive_ones_ii/MaxConsecutiveOnes.java b/src/main/java/max_consecutive_ones_ii/MaxConsecutiveOnes.java new file mode 100644 index 0000000..b574d77 --- /dev/null +++ b/src/main/java/max_consecutive_ones_ii/MaxConsecutiveOnes.java @@ -0,0 +1,32 @@ +package max_consecutive_ones_ii; + +import java.util.LinkedList; +import java.util.Queue; + +/** + * Created by lxie on 9/22/18. + */ +public class MaxConsecutiveOnes { + + public class Solution { + + public int findMaxConsecutiveOnes(int[] nums) { + int res = 0, left = 0, k = 1; + Queue q = new LinkedList<>(); + for (int right = 0; right < nums.length; ++right) { + if (nums[right] == 0) q.add(right); + if (q.size() > k) { + left = q.peek() + 1; q.poll(); + } + res = Math.max(res, right - left + 1); + } + return res; + } + } + + public class UnitTest { + + + + } +} diff --git a/src/main/java/max_points_on_a_line/MaxPointsonaLine.java b/src/main/java/max_points_on_a_line/MaxPointsonaLine.java new file mode 100644 index 0000000..a863fde --- /dev/null +++ b/src/main/java/max_points_on_a_line/MaxPointsonaLine.java @@ -0,0 +1,46 @@ +package max_points_on_a_line; + +import java.awt.Point; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + + +public class MaxPointsonaLine { + + public class Solution { + + public int maxPoints(Point[] points) { + int res = 0; + Map m = new HashMap(); + for (int i = 0; i < points.length; ++i) { + m.clear(); + m.put((float) Integer.MIN_VALUE, 0); + int duplicate = 1; + for (int j = 0; j < points.length; ++j) { + if (j == i) continue; + if (points[i].x == points[j].x && points[i].y == points[j].y) { + ++duplicate; + continue; + } + float slope = (points[i].x == points[j].x) ? (float) Integer.MAX_VALUE + : (float) (points[j].y - points[i].y) / (points[j].x - points[i].x); + if (m.containsKey(slope)) { + m.put(slope, m.get(slope) + 1); + } else { + m.put(slope, 1); + } + } + for (Map.Entry entry : m.entrySet()) { + res = Math.max(res, entry.getValue() + duplicate); + } + } + return res; + } + } + + public static class UnitTest { + + } +} diff --git a/src/main/java/max_product_of_word_lengths/MaxProdWordLenghs.java b/src/main/java/max_product_of_word_lengths/MaxProdWordLenghs.java new file mode 100644 index 0000000..1a94a75 --- /dev/null +++ b/src/main/java/max_product_of_word_lengths/MaxProdWordLenghs.java @@ -0,0 +1,44 @@ +package max_product_of_word_lengths; + +import java.util.HashMap; +import java.util.Map; + +/** + * Created by lxie on 7/3/18. + */ +public class MaxProdWordLenghs { + + public class Solution { + + public int maxProduct(String[] words) { + int res = 0; + Map m = new HashMap<>(); + for (String word : words) { + int mask = 0; + for (char c : word.toCharArray()) { + mask |= 1 << (c - 'a'); + } + if (!m.containsKey(mask)) { + m.put(mask, word.length()); + } else { + m.put(mask, Math.max(m.get(mask), word.length())); + } + + for (Map.Entry a : m.entrySet()) { + if ((mask & a.getKey()) == 0) { + res = Math.max(res, (int)word.length() * a.getValue()); + } + } + } + return res; + } + } + + public class UnitTest { + + + + } + + +} diff --git a/src/main/java/max_size_subarray_sum_equals_k/MaxSizeSubarraySumK.java b/src/main/java/max_size_subarray_sum_equals_k/MaxSizeSubarraySumK.java new file mode 100644 index 0000000..582b564 --- /dev/null +++ b/src/main/java/max_size_subarray_sum_equals_k/MaxSizeSubarraySumK.java @@ -0,0 +1,32 @@ +package max_size_subarray_sum_equals_k; + +import java.util.HashMap; +import java.util.Map; + +/** + * Created by lxie on 9/24/18. + */ +public class MaxSizeSubarraySumK { + + public class Solution { + + public int maxSubArrayLen(int[] nums, int k) { + int sum = 0, res = 0; + Map m = new HashMap<>(); + for (int i = 0; i < nums.length; ++i) { + sum += nums[i]; + if (sum == k) res = i + 1; + else if (m.containsKey(sum - k)) res = Math.max(res, i - m.get(sum - k)); + if (!m.containsKey(sum)) m.put(sum, i); // records earliest idx only + } + return res; + } + } + + public class UnitTest { + + + + } + +} diff --git a/src/main/java/max_square/MaxSquare.java b/src/main/java/max_square/MaxSquare.java new file mode 100644 index 0000000..0d95cb8 --- /dev/null +++ b/src/main/java/max_square/MaxSquare.java @@ -0,0 +1,38 @@ +package max_square; + +/** + * Created by lxie on 2/9/18. + */ +public class MaxSquare { + + public class Solution { + public int maximalSquare(char[][] matrix) { + int res = 0; + for (int i = 0; i < matrix.length; ++i) { + int[] v = new int[matrix[i].length]; + for (int j = i; j < matrix.length; ++j) { + for (int k = 0; k < matrix[j].length; ++k) { + if (matrix[j][k] == '1') ++v[k]; + } + res = Integer.max(res, getSquareArea(v, j - i + 1)); + } + } + return res; + } + int getSquareArea(int[]v, int k) { + if (v.length < k) return 0; + int count = 0; + for (int i = 0; i < v.length; ++i) { + if (v[i] != k) count = 0; + else ++count; + if (count == k) return k * k; + } + return 0; + } + } + + public static class UnitTest { + + } + +} diff --git a/src/main/java/max_sum_3_nonoverlapping_subarrays/Sum3NonOverlappingSubarrays.java b/src/main/java/max_sum_3_nonoverlapping_subarrays/Sum3NonOverlappingSubarrays.java new file mode 100644 index 0000000..fd7383f --- /dev/null +++ b/src/main/java/max_sum_3_nonoverlapping_subarrays/Sum3NonOverlappingSubarrays.java @@ -0,0 +1,58 @@ +package max_sum_3_nonoverlapping_subarrays; + +import java.util.Arrays; + +/** + * Created by lxie on 9/13/18. + */ +public class Sum3NonOverlappingSubarrays { + + public class Solution { + + public int[] maxSumOfThreeSubarrays(int[] nums, int k) { + int n = nums.length, mx = Integer.MIN_VALUE; + int[] sums = new int[n+1]; + int[] res = new int[3]; + int[] left = new int[n]; + int[] right = new int[n]; Arrays.fill(right, n-k); + for (int i = 0; i < n; ++i) sums[i+1] = sums[i] + nums[i]; // sums[0] = 0 + + for (int i = k, total = sums[k] - sums[0]; i < n; ++i) { + if (sums[i + 1] - sums[i + 1 - k] > total) { + left[i] = i + 1 - k; + total = sums[i + 1] - sums[i + 1 - k]; + } else { + left[i] = left[i - 1]; + } + } + for (int i = n - 1 - k, total = sums[n] - sums[n - k]; i >= 0; --i) { + if (sums[i + k] - sums[i] >= total) { + right[i] = i; + total = sums[i + k] - sums[i]; + } else { + right[i] = right[i + 1]; + } + } + for (int i = k; i <= n - 2 * k; ++i) { + int l = left[i - 1], r = right[i + k]; + // total = left_largest + current + right_largest + int total = (sums[i + k] - sums[i]) + (sums[l + k] - sums[l]) + (sums[r + k] - sums[r]); + if (mx < total) { + mx = total; + res[0] = l; res[1] = i; res[2] = r; + } + } + return res; + } + + + + + } + + public class UnitTest { + + + } + +} diff --git a/src/main/java/max_sum_sub_matrix/MaxSumSubMatrix.java b/src/main/java/max_sum_sub_matrix/MaxSumSubMatrix.java new file mode 100644 index 0000000..6d6f3dd --- /dev/null +++ b/src/main/java/max_sum_sub_matrix/MaxSumSubMatrix.java @@ -0,0 +1,53 @@ +package max_sum_sub_matrix; + +import com.google.common.collect.BoundType; +import com.google.common.collect.Multiset; +import com.google.common.collect.TreeMultiset; + +import java.util.Arrays; + +/** + * Created by lxie on 9/11/17. + */ +public class MaxSumSubMatrix { + + public static class Solution { + public int maxSumSubmatrix(int[][] matrix, int kval) { + if (matrix.length == 0 || matrix[0].length == 0) { + return 0; + } + int m = matrix.length, n = matrix[0].length, res = Integer.MIN_VALUE; + for (int i = 0; i < n; ++i) { + int[] sum = new int[m]; + Arrays.fill(sum, 0); + for (int j = i; j < n; ++j) { + for (int k = 0; k < m; ++k) { + sum[k] += matrix[k][j]; + } + int curSum = 0, curMax = Integer.MIN_VALUE; + TreeMultiset s = TreeMultiset.create(); + s.add(0); + for(int a : sum){ + curSum += a; + Multiset.Entry it = s.tailMultiset(curSum - kval, BoundType.CLOSED).firstEntry(); + if (it != null) curMax = Math.max(curMax, curSum - it.getElement()); + s.add(curSum); + } + res = Math.max(res, curMax); + } + } + return res; + } + + + } + + + public static void main(String[] args) { + Solution sol = new Solution(); + int[][] input = {{1,0,1}, {0, -2, 3}}; + int ret = sol.maxSumSubmatrix(input, 2); + System.out.println("result = " + ret); + } + +} diff --git a/src/main/java/max_xor_two_numbers_in_array/MaxXorTwoNumbersInArray.java b/src/main/java/max_xor_two_numbers_in_array/MaxXorTwoNumbersInArray.java new file mode 100644 index 0000000..a459789 --- /dev/null +++ b/src/main/java/max_xor_two_numbers_in_array/MaxXorTwoNumbersInArray.java @@ -0,0 +1,39 @@ +package max_xor_two_numbers_in_array; + +import java.util.HashSet; +import java.util.Set; + +/** + * Created by lxie on 8/31/18. + */ +public class MaxXorTwoNumbersInArray { + + public class Solution { + + public int findMaximumXOR(int[] nums) { + int res = 0, mask = 0; + for (int i = 31; i >= 0; --i) { + mask |= (1 << i); + Set s = new HashSet<>(); + for (int num : nums) { + s.add(num & mask); + } + int t = res | (1 << i); + for (int prefix : s) { + if (s.contains(t ^ prefix)) { + res = t; + break; + } + } + } + return res; + } + } + + public class UnitTest { + + + + } + +} diff --git a/src/main/java/maximal_rectangle/MaximalRectangle.java b/src/main/java/maximal_rectangle/MaximalRectangle.java new file mode 100644 index 0000000..062fcc4 --- /dev/null +++ b/src/main/java/maximal_rectangle/MaximalRectangle.java @@ -0,0 +1,49 @@ +package maximal_rectangle; + +import java.util.Stack; + +public class MaximalRectangle { + + public static class Solution { + public int maximalRectangle(char[][] matrix) { + int res = 0; + int[] height = new int[matrix[0].length + 1]; + for (int i = 0; i < matrix.length; ++i) { + for (int j = 0; j < matrix[i].length; ++j) { + height[j] = matrix[i][j] == '0' ? 0 : (1 + height[j]); + } + res = Math.max(res, largestRectangleArea(height)); // LC 84 + } + return res; + } + + // LC 84 + private int largestRectangleArea(int[] height) { + int res = 0; + Stack s = new Stack(); + height[height.length-1] = 0; + for (int i = 0; i < height.length; ++i) { + if (s.empty() || height[s.peek()] <= height[i]) s.push(i); + else { + int tmp = s.peek(); + s.pop(); + res = Math.max(res, height[tmp] * (s.empty() ? i : (i - s.peek() - 1))); + --i; + } + } + return res; + } + } + + public static void main(String[] args) { + Solution sol = new Solution(); + char[][] matrix = { + {'1', '0', '1', '0', '0'}, + {'1', '0', '1', '1', '1'}, + {'1', '1', '1', '1', '1'}, + {'1', '0', '0', '1', '0'} + }; + System.out.println(sol.maximalRectangle(matrix)); + + } +} diff --git a/src/main/java/maximum_gap/MaximumGap.java b/src/main/java/maximum_gap/MaximumGap.java new file mode 100644 index 0000000..0d72f75 --- /dev/null +++ b/src/main/java/maximum_gap/MaximumGap.java @@ -0,0 +1,48 @@ +package maximum_gap; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +public class MaximumGap { + + public class Solution { + public int maximumGap(int[] numss) { + if (numss.length == 0) return 0; + int mx = Integer.MIN_VALUE, mn = Integer.MAX_VALUE, n = numss.length; + for (int d : numss) { + mx = Integer.max(mx, d); + mn = Integer.min(mn, d); + } + int size = (mx - mn) / n + 1; + int bucket_nums = (mx - mn) / size + 1; + + int[] bucket_min = new int[bucket_nums]; + int[] bucket_max = new int[bucket_nums]; + Arrays.fill(bucket_min, Integer.MAX_VALUE); + Arrays.fill(bucket_max, Integer.MIN_VALUE); + + Set s = new HashSet<>(); + + for (int d : numss) { + int idx = (d - mn) / size; + bucket_min[idx] = Integer.min(bucket_min[idx], d); + bucket_max[idx] = Integer.max(bucket_max[idx], d); + s.add(idx); + } + int pre = 0, res = 0; + for (int i = 1; i < n; ++i) { + if (!s.contains(i)) continue; + res = Integer.max(res, bucket_min[i] - bucket_max[pre]); + pre = i; + } + return res; + } + + } + + public static class UnitTest { + + } +} + diff --git a/src/main/java/maximum_product_subarray/MaximumProductSubarray.java b/src/main/java/maximum_product_subarray/MaximumProductSubarray.java new file mode 100644 index 0000000..d36caf8 --- /dev/null +++ b/src/main/java/maximum_product_subarray/MaximumProductSubarray.java @@ -0,0 +1,42 @@ +package maximum_product_subarray; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +public class MaximumProductSubarray { + + public class Solution { + public int maxProduct(int[] A) { + assert A.length != 0; + int globalMax = A[0]; + int prevMax = A[0]; + int prevMin = A[0]; + for (int i = 1; i < A.length; i++) { + int max; + int min; + if (A[i] > 0) { + max = Math.max(A[i], prevMax * A[i]); + min = Math.min(A[i], prevMin * A[i]); + } else { + max = Math.max(A[i], prevMin * A[i]); + min = Math.min(A[i], prevMax * A[i]); + } + globalMax = Math.max(globalMax, max); + prevMax = max; + prevMin = min; + } + return globalMax; + } + } + + public static class UnitTest { + + @Test + public void testMaxProduct() { + Solution s = new MaximumProductSubarray().new Solution(); + assertEquals(12, s.maxProduct(new int[]{-4, -3, -2})); + } + } +} + diff --git a/src/main/java/maximum_swap/MaximumSwap.java b/src/main/java/maximum_swap/MaximumSwap.java new file mode 100644 index 0000000..be7d30e --- /dev/null +++ b/src/main/java/maximum_swap/MaximumSwap.java @@ -0,0 +1,37 @@ +package maximum_swap; + +/** + * Created by lxie on 9/27/18. + */ +public class MaximumSwap { + + public class Solution { + + public int maximumSwap(int num) { + char[] res = Integer.toString(num).toCharArray(); + char[] back = res.clone(); + for (int i = back.length - 2; i >= 0; --i) { + back[i] = back[i] < back[i + 1] ? back[i + 1] : back[i]; + } + for (int i = 0; i < res.length; ++i) { + if (res[i] == back[i]) continue; + for (int j = res.length - 1; j > i; --j) { + if (res[j] == back[i]) { + char tmp = res[j]; + res[j] = res[i]; + res[i] = tmp; + return Integer.parseInt(new String(res)); + } + } + } + return num; + } + } + + public class UnitTest { + + + } + + +} diff --git a/src/main/java/maximum_vacation_days/MaximumVacationDays.java b/src/main/java/maximum_vacation_days/MaximumVacationDays.java new file mode 100644 index 0000000..541b53b --- /dev/null +++ b/src/main/java/maximum_vacation_days/MaximumVacationDays.java @@ -0,0 +1,34 @@ +package maximum_vacation_days; + +/** + * Created by lxie on 8/20/18. + */ +public class MaximumVacationDays { + + public class Solution { + + public int maxVacationDays(int[][] flights, int[][] days) { + int n = flights.length, k = days[0].length, res = 0; + int[][] dp = new int[n][k]; + for (int j = k - 1; j >= 0; --j) { + for (int i = 0; i < n; ++i) { + dp[i][j] = days[i][j]; + for (int p = 0; p < n; ++p) { + if ((i == p || (flights[i][p]) != 0 && j < k - 1)) { + dp[i][j] = Math.max(dp[i][j], dp[p][j + 1] + days[i][j]); + } + if (j == 0 && (i == 0 || flights[0][i] != 0)) + res = Math.max(res, dp[i][0]); + } + } + } + return res; + } + + } + + public class UnitTest { + + + } +} diff --git a/src/main/java/median_of_two_sorted_arrays/MedianofTwoSortedArrays.java b/src/main/java/median_of_two_sorted_arrays/MedianofTwoSortedArrays.java index a601e3a..7cffcee 100644 --- a/src/main/java/median_of_two_sorted_arrays/MedianofTwoSortedArrays.java +++ b/src/main/java/median_of_two_sorted_arrays/MedianofTwoSortedArrays.java @@ -1,45 +1,39 @@ package median_of_two_sorted_arrays; +import org.junit.Test; + +import java.util.Arrays; + +import static org.junit.Assert.assertEquals; + public class MedianofTwoSortedArrays { public class Solution { - private double findMedianSortedArrays(int A[], int left, int right, - int B[]) { - if (left > right) { - return findMedianSortedArrays(B, - Math.max(0, (A.length + B.length) / 2 - A.length), - Math.min(B.length - 1, (A.length + B.length) / 2), A); - } - int i = (left + right) / 2; - int j = (A.length + B.length) / 2 - i - 1; - if (j >= 0 && A[i] < B[j]) { - return findMedianSortedArrays(A, i + 1, right, B); - } - if (j < B.length - 1 && A[i] > B[j + 1]) { - return findMedianSortedArrays(A, left, i - 1, B); - } - - if ((A.length + B.length) % 2 == 0) { - if (i > 0) { - int pre = j < 0 ? A[i - 1] : Math.max(A[i - 1], B[j]); - return (A[i] + pre) / 2.0; - } else { - return (A[i] + B[j]) / 2.0; - } + public double findMedianSortedArrays(int[] nums1, int[] nums2) { + int m = nums1.length, n = nums2.length, left = (m + n + 1) / 2, right = (m + n + 2) / 2; + return (findKth(nums1, nums2, left) + findKth(nums1, nums2, right)) / 2.0; + } + int findKth(int[] nums1, int[] nums2, int k) { + int m = nums1.length, n = nums2.length; + if (m > n) return findKth(nums2, nums1, k); + if (m == 0) return nums2[k - 1]; + if (k == 1) return Math.min(nums1[0], nums2[0]); + int i = Math.min(m, k / 2), j = Math.min(n, k / 2); + if (nums1[i - 1] > nums2[j - 1]) { + return findKth(nums1, Arrays.copyOfRange(nums2, j, n), k - j); } else { - return A[i]; + return findKth(Arrays.copyOfRange(nums1, i, m), nums2, k - i); } } - - public double findMedianSortedArrays(int A[], int B[]) { - return findMedianSortedArrays(A, - Math.max(0, (A.length + B.length) / 2 - B.length), - Math.min(A.length - 1, (A.length + B.length) / 2), B); - } } public static class UnitTest { + @Test + public void testFindMedianSortedArrays() { + Solution s = new MedianofTwoSortedArrays().new Solution(); + assertEquals(2.5, s.findMedianSortedArrays(new int[]{3, 4}, new int[]{1, 2}), 1E-6); + } } } diff --git a/src/main/java/meeting_rooms/MeetingRooms.java b/src/main/java/meeting_rooms/MeetingRooms.java new file mode 100644 index 0000000..5c3fbd7 --- /dev/null +++ b/src/main/java/meeting_rooms/MeetingRooms.java @@ -0,0 +1,39 @@ +package meeting_rooms; + +import common.Interval; + +import java.util.Arrays; +import java.util.Comparator; + +/** + * Created by lxie on 5/25/18. + */ +public class MeetingRooms { + + public class Solution { + + public boolean canAttendMeetings(Interval[] intervals) { + if(intervals == null || intervals.length == 0) return true; + Arrays.sort(intervals, new Comparator(){ + @Override + public int compare(Interval i1, Interval i2){ + return i1.start - i2.start; + } + }); + for (int i = 1; i < intervals.length; ++i) { + if (intervals[i].start < intervals[i - 1].end) { + return false; + } + } + return true; + } + } + + public class UnitTest { + + + + } + + +} diff --git a/src/main/java/meeting_rooms_ii/MeetingRoomsII.java b/src/main/java/meeting_rooms_ii/MeetingRoomsII.java new file mode 100644 index 0000000..1f8412b --- /dev/null +++ b/src/main/java/meeting_rooms_ii/MeetingRoomsII.java @@ -0,0 +1,56 @@ +package meeting_rooms_ii; + +import common.Interval; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; + +import static java.lang.Integer.max; + +/** + * Created by lxie on 5/25/18. + */ +public class MeetingRoomsII { + + public static class Solution { + + public int minMeetingRooms(List intervals) { + Map m = new TreeMap<>(); + for (Interval a : intervals) { + if (m.containsKey(a.start)) { + m.put(a.start, m.get(a.start)+1); + } else { + m.put(a.start, 1); + } + + if (m.containsKey(a.end)) { + m.put(a.end, m.get(a.end)-1); + } else{ + m.put(a.end, -1); + } + } + int rooms = 0, res = 0; + for ( Map.Entry i : m.entrySet()) { + res = max(res, rooms += i.getValue()); + } + return res; + } + + } + + public static void main(String[] args) { + Solution sol = new Solution(); + + List intervals = new ArrayList<>(); + intervals.add(new Interval(0, 30)); + intervals.add(new Interval(5, 10)); + intervals.add(new Interval(15, 20)); + + int res = sol.minMeetingRooms(intervals); + System.out.println("result is " + res); + } + + +} diff --git a/src/main/java/merge_intervals/MergeIntervals.java b/src/main/java/merge_intervals/MergeIntervals.java index a6f8a36..0ef9549 100644 --- a/src/main/java/merge_intervals/MergeIntervals.java +++ b/src/main/java/merge_intervals/MergeIntervals.java @@ -1,15 +1,17 @@ package merge_intervals; +import common.Interval; + import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; -import common.Interval; - public class MergeIntervals { public class Solution { public ArrayList merge(ArrayList intervals) { + ArrayList ans = new ArrayList(); + if (intervals.isEmpty()) return ans; Collections.sort(intervals, new Comparator() { @Override @@ -22,24 +24,17 @@ public int compare(Interval i1, Interval i2) { }); - ArrayList ans = new ArrayList(); - Interval newInterval = null; - for (Interval i : intervals) { - if (newInterval == null) { - newInterval = new Interval(i.start, i.end); + ans.add(intervals.get(0)); + for (int i = 1; i < intervals.size(); ++i) { + if (ans.get(ans.size()-1).end >= intervals.get(i).start) { + ans.get(ans.size()-1).end = Math.max(ans.get(ans.size()-1).end, + intervals.get(i).end); } else { - if (newInterval.end < i.start) { - ans.add(newInterval); - newInterval = new Interval(i.start, i.end); - } else { - newInterval.end = Math.max(newInterval.end, i.end); - } + ans.add(new Interval(intervals.get(i).start, intervals.get(i).end)); } } - if (newInterval != null) { - ans.add(newInterval); - } return ans; + } } diff --git a/src/main/java/merge_two_sorted_lists/MergeTwoSortedLists.java b/src/main/java/merge_two_sorted_lists/MergeTwoSortedLists.java index e199695..a0b0e65 100644 --- a/src/main/java/merge_two_sorted_lists/MergeTwoSortedLists.java +++ b/src/main/java/merge_two_sorted_lists/MergeTwoSortedLists.java @@ -6,43 +6,24 @@ public class MergeTwoSortedLists { public class Solution { public ListNode mergeTwoLists(ListNode l1, ListNode l2) { - ListNode head = null; - ListNode pre = null; - while (l1 != null && l2 != null) { - if (l1.val <= l2.val) { - if (head == null) { - head = l1; - } else { - pre.next = l1; - } - pre = l1; + ListNode dummy = new ListNode(0); + ListNode res = dummy; + ListNode cur = res; + while(l1 != null && l2 != null) { + if (l1.val < l2.val) { + cur.next = l1; l1 = l1.next; } else { - if (head == null) { - head = l2; - } else { - pre.next = l2; - } - pre = l2; + cur.next = l2; l2 = l2.next; } + cur = cur.next; } - if (l1 != null) { - if (head == null) { - head = l1; - } else { - pre.next = l1; - } - } - if (l2 != null) { - if (head == null) { - head = l2; - } else { - pre.next = l2; - } - } - return head; + if (l1 != null) cur.next = l1; + if (l2 != null) cur.next = l2; + return res.next; } + } public static class UnitTest { diff --git a/src/main/java/min_distance_between_bst_nodes/MinDistanceBSTNodes.java b/src/main/java/min_distance_between_bst_nodes/MinDistanceBSTNodes.java new file mode 100644 index 0000000..186be2d --- /dev/null +++ b/src/main/java/min_distance_between_bst_nodes/MinDistanceBSTNodes.java @@ -0,0 +1,32 @@ +package min_distance_between_bst_nodes; + +import common.TreeNode; + +/** + * Created by lxie on 7/11/18. + */ +public class MinDistanceBSTNodes { + + public class Solution { + + public int minDiffInBST(TreeNode root) { + int[] res = {Integer.MAX_VALUE}; + int[] pre = {-1}; + helper(root, pre, res); + return res[0]; + } + + private void helper(TreeNode node, int[] pre, int[] res) { + if (node == null) return; + helper(node.left, pre, res); + if (pre[0] != -1) res[0] = Math.min(res[0], node.val - pre[0]); + pre[0] = node.val; + helper(node.right, pre, res); + } + } + + public class UnitTest { + + } + +} diff --git a/src/main/java/min_stack/MinStack.java b/src/main/java/min_stack/MinStack.java new file mode 100644 index 0000000..dbcb875 --- /dev/null +++ b/src/main/java/min_stack/MinStack.java @@ -0,0 +1,38 @@ +package min_stack; + +import java.util.Stack; + +public class MinStack { + + private Stack _stack = new Stack(); + private Stack _minStack = new Stack(); + + + /** initialize your data structure here. */ + public MinStack() { + + } + + public void push(Integer x) { + _stack.push(x); + if (_minStack.empty() || x <= _minStack.peek()) _minStack.push(x); + } + + public void pop() { + if (!_stack.empty()) { + if (_stack.peek() == _minStack.peek()) _minStack.pop(); + _stack.pop(); + } + } + + public int top() { + if (!_stack.empty()) return _stack.peek(); + return 0; + } + + public int getMin() { + if (!_minStack.empty()) return _minStack.peek(); + return 0; + } + +} diff --git a/src/main/java/min_unique_word_abbrev/MinUniqueWordAbbrev.java b/src/main/java/min_unique_word_abbrev/MinUniqueWordAbbrev.java new file mode 100644 index 0000000..e74c569 --- /dev/null +++ b/src/main/java/min_unique_word_abbrev/MinUniqueWordAbbrev.java @@ -0,0 +1,86 @@ +package min_unique_word_abbrev; + +import common.Pair; + +import java.util.Comparator; +import java.util.Map; +import java.util.PriorityQueue; + +/** + * Created by lxie on 8/26/18. + */ +public class MinUniqueWordAbbrev { + + public class Solution { + public String minAbbreviation(String target, String[] dictionary) { + if (dictionary.length == 0) return Integer.toString((int)target.length()); + //priority_queue, vector>, greater>> q; + PriorityQueue> q; + q = generate(target); + while (!q.isEmpty()) { + Map.Entry t = q.peek(); q.poll(); + boolean no_conflict = true; + for (String word : dictionary) { + if (valid(word, t.getValue())) { + no_conflict = false; + break; + } + } + if (no_conflict) return t.getValue(); + } + return ""; + } + + + private PriorityQueue> generate(String target) { + PriorityQueue> res = new PriorityQueue<>(50, new Comparator>() { + @Override + public int compare(Map.Entry o1, Map.Entry o2) { + return o1.getKey() - o2.getKey(); + } + }); + for (int i = 0; i < Math.pow(2, target.length()); ++i) { + String out = ""; + int cnt = 0, size = 0; + for (int j = 0; j < target.length(); ++j) { + if (((i >> j) & 1) != 0) ++cnt; + else { + if (cnt != 0) { + out += Integer.toString(cnt); + cnt = 0; + ++size; + } + out += target.charAt(j); + ++size; + } + } + if (cnt > 0) { + out += Integer.toString(cnt); + ++size; + } + res.add(Pair.of(size, out)); + } + return res; + } + + private boolean valid(String word, String abbr) { + int m = word.length(), n = abbr.length(), p = 0, cnt = 0; + for (int i = 0; i < abbr.length(); ++i) { + if (abbr.charAt(i) >= '0' && abbr.charAt(i) <= '9') { + if (cnt == 0 && abbr.charAt(i) == '0') return false; + cnt = 10 * cnt + abbr.charAt(i) - '0'; + } else { + p += cnt; + if (p >= m || word.charAt(p++) != abbr.charAt(i)) return false; + cnt = 0; + } + } + return p + cnt == m; + } + } + + public class UnitTest { + + + } +} diff --git a/src/main/java/minimum_absolute_diff_bst/MinAbsoluteDiffBst.java b/src/main/java/minimum_absolute_diff_bst/MinAbsoluteDiffBst.java new file mode 100644 index 0000000..6b99dbd --- /dev/null +++ b/src/main/java/minimum_absolute_diff_bst/MinAbsoluteDiffBst.java @@ -0,0 +1,33 @@ +package minimum_absolute_diff_bst; + +import common.TreeNode; + +/** + * Created by lxie on 9/8/18. + */ +public class MinAbsoluteDiffBst { + + public class Solution { + + public int getMinimumDifference(TreeNode root) { + int res[] = {Integer.MAX_VALUE}, pre[] = {-1}; + inorder(root, pre, res); + return res[0]; + } + + private void inorder(TreeNode root, int[] pre, int[] res) { + if (root == null) return; + inorder(root.left, pre, res); + if (pre[0] != -1) res[0] = Math.min(res[0], root.val - pre[0]); + pre[0] = root.val; + inorder(root.right, pre, res); + } + + } + + public class UnitTest { + + + + } +} diff --git a/src/main/java/minimum_height_trees/MinimumHeightTrees.java b/src/main/java/minimum_height_trees/MinimumHeightTrees.java new file mode 100644 index 0000000..22b3fe0 --- /dev/null +++ b/src/main/java/minimum_height_trees/MinimumHeightTrees.java @@ -0,0 +1,40 @@ +package minimum_height_trees; + +import java.util.*; + +/** + * Created by lxie on 1/9/18. + */ +public class MinimumHeightTrees { + + class Solution { + public List findMinHeightTrees(int n, int[][] edges) { + if (n == 1) return Collections.singletonList(0); + List leaves = new ArrayList<>(); + List> adj = new ArrayList<>(n); + for (int i = 0; i < n; ++i) adj.add(new HashSet<>()); + for (int[] edge : edges) { + adj.get(edge[0]).add(edge[1]); + adj.get(edge[1]).add(edge[0]); + } + for (int i = 0; i < n; ++i) { + if (adj.get(i).size() == 1) leaves.add(i); + } + while (n > 2) { + n -= leaves.size(); + List newLeaves = new ArrayList<>(); + for (int i : leaves) { + int t = adj.get(i).iterator().next(); + adj.get(t).remove(i); + if (adj.get(t).size() == 1) newLeaves.add(t); + } + leaves = newLeaves; + } + return leaves; + } + } + + public static class UnitTest { + + } +} diff --git a/src/main/java/minimum_path_sum/MinimumPathSum.java b/src/main/java/minimum_path_sum/MinimumPathSum.java index f82d1b0..e8a61dc 100644 --- a/src/main/java/minimum_path_sum/MinimumPathSum.java +++ b/src/main/java/minimum_path_sum/MinimumPathSum.java @@ -4,16 +4,17 @@ public class MinimumPathSum { public class Solution { public int minPathSum(int[][] grid) { - assert grid != null && grid.length != 0 && grid[0].length != 0; - int[] dp = new int[grid[0].length]; - for (int i = 0; i < grid.length; i++) { - dp[0] = i == 0 ? grid[0][0] : dp[0] + grid[i][0]; - for (int j = 1; j < grid[0].length; j++) { - dp[j] = i == 0 ? dp[j - 1] : Math.min(dp[j], dp[j - 1]); - dp[j] += grid[i][j]; + int m = grid.length, n = grid[0].length; + int[][] dp = new int[m][n]; + dp[0][0] = grid[0][0]; + for (int i = 1; i < m; ++i) dp[i][0] = grid[i][0] + dp[i - 1][0]; + for (int i = 1; i < n; ++i) dp[0][i] = grid[0][i] + dp[0][i - 1]; + for (int i = 1; i < m; ++i) { + for (int j = 1; j < n; ++j) { + dp[i][j] = grid[i][j] + Math.min(dp[i - 1][j], dp[i][j - 1]); } } - return dp[grid[0].length - 1]; + return dp[m - 1][n - 1]; } } diff --git a/src/main/java/minimum_size_subarray_sum/MinSizeSubarraySum.java b/src/main/java/minimum_size_subarray_sum/MinSizeSubarraySum.java new file mode 100644 index 0000000..7d14d14 --- /dev/null +++ b/src/main/java/minimum_size_subarray_sum/MinSizeSubarraySum.java @@ -0,0 +1,27 @@ +package minimum_size_subarray_sum; + +/** + * Created by lxie on 9/29/18. + */ +public class MinSizeSubarraySum { + + public class Solution { + + public int minSubArrayLen(int s, int[] nums) { + int res = Integer.MAX_VALUE, left = 0, sum = 0; + for (int i = 0; i < nums.length; ++i) { + sum += nums[i]; + while (left <= i && sum >= s) { + res = Math.min(res, i - left + 1); + sum -= nums[left++]; + } + } + return res == Integer.MAX_VALUE ? 0 : res; + } + } + + public class UnitTest { + + + } +} diff --git a/src/main/java/minimum_window_substring/MinimumWindowSubstring.java b/src/main/java/minimum_window_substring/MinimumWindowSubstring.java new file mode 100644 index 0000000..6de9004 --- /dev/null +++ b/src/main/java/minimum_window_substring/MinimumWindowSubstring.java @@ -0,0 +1,41 @@ +package minimum_window_substring; + +public class MinimumWindowSubstring { + + public class Solution { + public String minWindow(String S, String T) { + int[] need = new int[256]; + for(int i = 0; i < T.length(); i++) + need[T.charAt(i)]++; + int[] found = new int[256]; + + int count = 0; + int minLen = S.length()+1; + int minBegin = 0; + for(int begin = 0, end = 0; end < S.length(); ++end){ + char ch = S.charAt(end); + if(need[ch] == 0) continue; + if(++found[ch] <= need[ch]) count++; + if(count == T.length()){ + while(need[S.charAt(begin)] == 0 || + found[S.charAt(begin)] > need[S.charAt(begin)]){ + if(found[S.charAt(begin)] > need[S.charAt(begin)]) + found[S.charAt(begin)]--; + begin++; + } + int leng = end - begin + 1; + if(leng < minLen){ + minLen = leng; + minBegin = begin; + } + } + } + return minLen > S.length()?"":S.substring(minBegin,minBegin+minLen); + } + + } + + public static class UnitTest { + + } +} diff --git a/src/main/java/missing_range/MissingRange.java b/src/main/java/missing_range/MissingRange.java new file mode 100644 index 0000000..c731b4b --- /dev/null +++ b/src/main/java/missing_range/MissingRange.java @@ -0,0 +1,32 @@ +package missing_range; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by lxie on 8/19/18. + */ +public class MissingRange { + + public class Solution { + public List findMissingRanges(List nums, int lower, int upper) { + List res = new ArrayList<>(); + int l = lower; + for (int i = 0; i <= nums.size(); ++i) { + int r = (i < nums.size() && nums.get(i) <= upper) ? nums.get(i) : upper + 1; + if (l == r) ++l; + else if (r > l) { + res.add(r - l == 1 ? Integer.toString(l) : Integer.toString(l) + "->" + + Integer.toString(r - 1)); + l = r + 1; + } + } + return res; + } + } + + public class UnitTest { + + + } +} diff --git a/src/main/java/moving_average_data_stream/MovingAvgDataStream.java b/src/main/java/moving_average_data_stream/MovingAvgDataStream.java new file mode 100644 index 0000000..e710226 --- /dev/null +++ b/src/main/java/moving_average_data_stream/MovingAvgDataStream.java @@ -0,0 +1,30 @@ +package moving_average_data_stream; + +import java.util.LinkedList; + +/** + * Created by lxie on 12/9/17. + */ +public class MovingAvgDataStream { + private LinkedList queue = new LinkedList<>(); + private int size; + private double sum; + + public MovingAvgDataStream(int size) { + this.size = size; + } + + public double next(int val) { + if (queue.size() >= size) { + sum -= queue.getFirst(); + queue.remove(0); + } + queue.add(val); + sum += val; + return sum/queue.size(); + } + + public static class UnitTest { + + } +} diff --git a/src/main/java/multiply_strings/MultiplyStrings.java b/src/main/java/multiply_strings/MultiplyStrings.java new file mode 100644 index 0000000..b4c9c50 --- /dev/null +++ b/src/main/java/multiply_strings/MultiplyStrings.java @@ -0,0 +1,33 @@ +package multiply_strings; + +import java.util.Arrays; + +public class MultiplyStrings { + + public class Solution { + + public String multiply(String num1, String num2) { + if (num1.charAt(0) == '0' || num2.charAt(0) == '0') return "0"; + int n1 = num1.length(), n2 = num2.length(), n = (n1 + n2); + int[] r = new int[n]; + char[] s = new char[n]; + Arrays.fill(s, '0'); + + for (int i = 0; i < n1; ++i) { + for (int j = 0; j < n2; ++j) { + r[i + j + 1] += (num1.charAt(i) - '0') * (num2.charAt(j) - '0'); + } + } + + for (int i = n - 1; i > 0; --i) { + if (r[i] > 9) r[i - 1] += r[i] / 10; + s[i] += r[i] % 10; + } + s[0] += r[0]; + return s[0] == '0' ? new String(s).substring(1) : new String(s); + } + } + + public static class UnitTest { + } +} diff --git a/src/main/java/n_queens/NQueens.java b/src/main/java/n_queens/NQueens.java new file mode 100644 index 0000000..572a9d2 --- /dev/null +++ b/src/main/java/n_queens/NQueens.java @@ -0,0 +1,54 @@ +package n_queens; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class NQueens { + + public class Solution { + public List> solveNQueens(int n) { + List > res = new ArrayList<>(); + int[] pos = new int[n]; + for(int i = 0; i < n; ++i) pos[i] = -1; + solveNQueensDFS(pos, 0, res); + return res; + } + + private void solveNQueensDFS(int[] pos, int row, List > res) { + int n = pos.length; + if (row == n) { + List out = new ArrayList<>(); + for (int i = 0; i < n; ++i) { + char[] s = new char[n]; + Arrays.fill(s, '.'); + s[pos[i]] = 'Q'; + out.add(new String(s)); + } + res.add(new ArrayList<>(out)); + } else { + for (int col = 0; col < n; ++col) { + if (isValid(pos, row ,col)) { + pos[row] = col; + solveNQueensDFS(pos, row + 1, res); + pos[row] = -1; // back-tracking + } + } + } + } + + private boolean isValid(int[] pos, int row, int col) { + for (int i = 0; i < row; ++i) { + if (col == pos[i] || Math.abs(row - i) == Math.abs(col - pos[i])) { + return false; + } + } + return true; + } + + } + + public static class UnitTest { + + } +} diff --git a/src/main/java/nested_list_weight_sum/NestedListWeightSum.java b/src/main/java/nested_list_weight_sum/NestedListWeightSum.java new file mode 100644 index 0000000..9411934 --- /dev/null +++ b/src/main/java/nested_list_weight_sum/NestedListWeightSum.java @@ -0,0 +1,30 @@ +package nested_list_weight_sum; + +import common.NestedInteger; + +import java.util.List; + +/** + * Created by lxie on 1/27/18. + */ +public class NestedListWeightSum { + + public class Solution { + + public int depthSum(List nestedList) { + return helper(nestedList, 1); + } + int helper(List nl, int depth) { + int res = 0; + for (NestedInteger a : nl) { + res += a.isInteger() ? a.getInteger() * depth : helper(a.getList(), depth + 1); + } + return res; + } + } + + public static class UnitTest { + + } + +} diff --git a/src/main/java/nested_list_weight_sum_ii/NestedListWeightSumII.java b/src/main/java/nested_list_weight_sum_ii/NestedListWeightSumII.java new file mode 100644 index 0000000..68ca554 --- /dev/null +++ b/src/main/java/nested_list_weight_sum_ii/NestedListWeightSumII.java @@ -0,0 +1,42 @@ +package nested_list_weight_sum_ii; + +import common.NestedInteger; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by lxie on 1/27/18. + */ +public class NestedListWeightSumII { + + public class Solution { + + public int depthSumInverse(List nestedList) { + int res = 0; + List v = new ArrayList<>(); + for (NestedInteger a : nestedList) { + helper(a, 0, v); + } + for (int i = v.size() - 1; i >= 0; --i) { + res += v.get(i) * (v.size() - i); + } + return res; + } + void helper(NestedInteger ni, int depth, List v) { + if (depth >= v.size()) v.add(0); + if (ni.isInteger()) { + v.set(depth, v.get(depth) + ni.getInteger()); + } else { + for (NestedInteger a : ni.getList()) { + helper(a, depth + 1, v); + } + } + } + } + + public static class UnitTest { + + } + +} diff --git a/src/main/java/next_closest_time/NextClosestTime.java b/src/main/java/next_closest_time/NextClosestTime.java new file mode 100644 index 0000000..8d020ab --- /dev/null +++ b/src/main/java/next_closest_time/NextClosestTime.java @@ -0,0 +1,33 @@ +package next_closest_time; + +/** + * Created by lxie on 8/18/18. + */ +public class NextClosestTime { + + public String nextClosestTime(String time) { + StringBuilder res = new StringBuilder("0000"); + int[] v = {600, 60, 10, 1}; + int found = time.indexOf(":"); + int cur = Integer.parseInt(time.substring(0, found)) * 60 + + Integer.parseInt(time.substring(found + 1)); + for (int i = 1, d = 0; i <= 1440; ++i) { + int next = (cur + i) % 1440; + for (d = 0; d < 4; ++d) { + res.setCharAt(d, (char) ('0' + next / v[d])); + next %= v[d]; + if (time.indexOf(res.charAt(d)) < 0) break; + } + if (d >= 4) break; + } + return res.substring(0, 2) + ":" + res.substring(2); + } + + public static void main(String[] args) { + NextClosestTime n = new NextClosestTime(); + System.out.println(n.nextClosestTime("23:59")); + + } + + +} diff --git a/src/main/java/next_greater_element_ii/NextGreaterElementII.java b/src/main/java/next_greater_element_ii/NextGreaterElementII.java new file mode 100644 index 0000000..3ee802a --- /dev/null +++ b/src/main/java/next_greater_element_ii/NextGreaterElementII.java @@ -0,0 +1,33 @@ +package next_greater_element_ii; + +import java.util.Arrays; +import java.util.Stack; + +/** + * Created by lxie on 9/1/18. + */ +public class NextGreaterElementII { + + public class Solution { + public int[] nextGreaterElements(int[] nums) { + int n = nums.length; + int[] res = new int[n]; Arrays.fill(res, -1); + Stack st = new Stack<>(); + for (int i = 0; i < 2 * n; ++i) { + int num = nums[i % n]; + while (!st.empty() && nums[st.peek()] < num) { + res[st.peek()] = num; st.pop(); + } + if (i < n) st.push(i); // when i>n-1, we seek next larger for those in stack only + } + return res; + } + } + + public class UnitTest { + + + + } + +} diff --git a/src/main/java/next_permutation/NextPermutation.java b/src/main/java/next_permutation/NextPermutation.java new file mode 100644 index 0000000..6f89598 --- /dev/null +++ b/src/main/java/next_permutation/NextPermutation.java @@ -0,0 +1,40 @@ +package next_permutation; + +public class NextPermutation { + + public class Solution { + + public void nextPermutation(int[] num) { + int i, j, n = num.length; + for (i = n - 2; i >= 0; --i) { + if (num[i + 1] > num[i]) { + for (j = n - 1; j >= i; --j) { + if (num[j] > num[i]) break; + } + int tmp = num[i]; + num[i] = num[j]; + num[j] = tmp; + reverse(num, i + 1, num.length-1); + return; + } + } + reverse(num, 0, num.length-1); + + } + + private void reverse(int[] a, int start, int end) { + if (a.length == 0 || a.length == 1) return; + while (start < end) { + int tmp = a[start]; + a[start] = a[end]; + a[end] = tmp; + start++; end--; + } + + } + } + + public static class UnitTest { + + } +} diff --git a/src/main/java/nth_digit/NthDigit.java b/src/main/java/nth_digit/NthDigit.java new file mode 100644 index 0000000..eba5401 --- /dev/null +++ b/src/main/java/nth_digit/NthDigit.java @@ -0,0 +1,26 @@ +package nth_digit; + +/** + * Created by lxie on 8/28/18. + */ +public class NthDigit { + + public class Solution { + int findNthDigit(int n) { + long len = 1, cnt = 9, start = 1; + while (n > len * cnt) { + n -= len * cnt; + ++len; + cnt *= 10; + start *= 10; + } + start += (n - 1) / len; + String t = Long.toString(start); + return t.charAt((n - 1) % (int)len) - '0'; + } + } + + public class UnitTest { + + } +} diff --git a/src/main/java/number_of_1_bits/Numberof1Bits.java b/src/main/java/number_of_1_bits/Numberof1Bits.java new file mode 100644 index 0000000..7a430d4 --- /dev/null +++ b/src/main/java/number_of_1_bits/Numberof1Bits.java @@ -0,0 +1,16 @@ +package number_of_1_bits; + +public class Numberof1Bits { + + public class Solution { + public int hammingWeight(int n) { + int count = 0; + while (n != 0) { + count++; + n &= (n - 1); + } + return count; + } + } +} + diff --git a/src/main/java/number_of_boomerangs/NumberOfBoomerangs.java b/src/main/java/number_of_boomerangs/NumberOfBoomerangs.java new file mode 100644 index 0000000..5b3e900 --- /dev/null +++ b/src/main/java/number_of_boomerangs/NumberOfBoomerangs.java @@ -0,0 +1,39 @@ +package number_of_boomerangs; + +import java.util.HashMap; +import java.util.Map; + +/** + * Created by lxie on 7/12/18. + */ +public class NumberOfBoomerangs { + + public class Solution { + public int numberOfBoomerangs(int[][] points) { + int res = 0; + for (int i = 0; i < points.length; ++i) { + Map m = new HashMap<>(); + for (int j = 0; j < points.length; ++j) { + int a = points[i][0] - points[j][0]; + int b = points[i][1] - points[j][1]; + if (!m.containsKey(a * a + b * b)) { + m.put(a * a + b * b, 1); + } else { + m.put(a * a + b * b, m.get(a * a + b * b)+1); + } + } + for (Map.Entry entry : m.entrySet()) { + res += entry.getValue() * (entry.getValue() - 1); + } + } + return res; + } + + + } + + public class UnitTest { + + + } +} diff --git a/src/main/java/number_of_islands/NumberOfIslands.java b/src/main/java/number_of_islands/NumberOfIslands.java new file mode 100644 index 0000000..59ade04 --- /dev/null +++ b/src/main/java/number_of_islands/NumberOfIslands.java @@ -0,0 +1,45 @@ +package number_of_islands; + +/** + * Created by lxie on 1/23/18. + */ +public class NumberOfIslands { + + public class Solution { + public int numIslands(char[][] grid) { + if (grid.length == 0 || grid[0].length == 0) return 0; + int m = grid.length, n = grid[0].length, res = 0; + boolean[][] visited = new boolean[m][n]; + + for (int i = 0; i < m; ++i) { + for (int j = 0; j < n; ++j) { + if (grid[i][j] == '1' && !visited[i][j]) { + numIslandsDFS(grid, visited, i, j); + ++res; + } + } + } + return res; + } + + public void numIslandsDFS(char[][] grid, boolean[][] visited, int x, int y) { + if (x < 0 || x >= grid.length) return; + if (y < 0 || y >= grid[0].length) return; + if (grid[x][y] != '1' || visited[x][y]) return; + visited[x][y] = true; + numIslandsDFS(grid, visited, x - 1, y); + numIslandsDFS(grid, visited, x + 1, y); + numIslandsDFS(grid, visited, x, y - 1); + numIslandsDFS(grid, visited, x, y + 1); + } + + } + + public static class UnitTest { + + + + + } + +} diff --git a/src/main/java/number_of_islands_ii/NumberOfIslandsII.java b/src/main/java/number_of_islands_ii/NumberOfIslandsII.java new file mode 100644 index 0000000..5852c2e --- /dev/null +++ b/src/main/java/number_of_islands_ii/NumberOfIslandsII.java @@ -0,0 +1,54 @@ +package number_of_islands_ii; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by lxie on 1/23/18. + */ +public class NumberOfIslandsII { + + public class Solution { + + public List numIslands2(int m, int n, int[][] positions) { + List res = new ArrayList<>(); + if (m <= 0 || n <= 0) return res; + int[] roots = new int[m*n]; + for (int i=0; i= m || y < 0 || y >= n || roots[cur_id] == -1) continue; + int new_id = findRoots(roots, cur_id); + if (id != new_id) { + roots[id] = new_id; + id = new_id; + --cnt; + } + } + res.add(cnt); + } + return res; + } + + // union find + private int findRoots(int[] roots, int id) { + while (id != roots[id]) { + roots[id] = roots[roots[id]]; // path compression + id = roots[id]; + } + return id; + } + } + + public static class UnitTest { + + } + +} diff --git a/src/main/java/number_of_longest_increasing_subsequence/NumberOfLIS.java b/src/main/java/number_of_longest_increasing_subsequence/NumberOfLIS.java new file mode 100644 index 0000000..4186466 --- /dev/null +++ b/src/main/java/number_of_longest_increasing_subsequence/NumberOfLIS.java @@ -0,0 +1,42 @@ +package number_of_longest_increasing_subsequence; + +import java.util.Arrays; + +/** + * Created by lxie on 10/9/18. + */ +public class NumberOfLIS { + + public class Solution { + + public int findNumberOfLIS(int[] nums) { + int res = 0, mx = 0, n = nums.length; + int[] len = new int[n]; Arrays.fill(len, 1); + int[] cnt = new int[n]; Arrays.fill(cnt, 1); + for (int i = 0; i < n; ++i) { + for (int j = 0; j < i; ++j) { + if (nums[i] <= nums[j]) continue; + if (len[i] == len[j] + 1) cnt[i] += cnt[j]; + else if (len[i] < len[j] + 1) { + len[i] = len[j] + 1; + cnt[i] = cnt[j]; + } + } + if (mx == len[i]) res += cnt[i]; + else if (mx < len[i]) { + mx = len[i]; + res = cnt[i]; + } + } + return res; + } + + } + + public class UnitTest { + + + + } + +} diff --git a/src/main/java/ones_and_zeroes/OnesAndZeroes.java b/src/main/java/ones_and_zeroes/OnesAndZeroes.java new file mode 100644 index 0000000..93572a7 --- /dev/null +++ b/src/main/java/ones_and_zeroes/OnesAndZeroes.java @@ -0,0 +1,37 @@ +package ones_and_zeroes; + +/** + * Created by lxie on 9/10/18. + */ +public class OnesAndZeroes { + + public class Solution { + + public int findMaxForm(String[] strs, int m, int n) { + int[][] dp = new int[m+1][n+1]; + for (String str : strs) { + int zeros = 0, ones = 0; + for (char c : str.toCharArray()) { + if (c == '0') ++zeros; + else + ++ones; + } + for (int i = m; i >= zeros; --i) { + for (int j = n; j >= ones; --j) { + dp[i][j] = Math.max(dp[i][j], dp[i - zeros][j - ones] + 1); + } + } + } + return dp[m][n]; + } + + + } + + public class UnitTest { + + + } + + +} diff --git a/src/main/java/optimal_account_balance/OptimalAccountBalancing.java b/src/main/java/optimal_account_balance/OptimalAccountBalancing.java new file mode 100644 index 0000000..d39901e --- /dev/null +++ b/src/main/java/optimal_account_balance/OptimalAccountBalancing.java @@ -0,0 +1,60 @@ +package optimal_account_balance; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Created by lxie on 8/26/18. + */ +public class OptimalAccountBalancing { + + public int minTransfers(int[][] transactions) { + Map m = new HashMap<>(); + for (int[] t : transactions) { + if(m.containsKey(t[0])) + m.put(t[0], m.get(t[0]) - t[2]); + else + m.put(t[0], -t[2]); + + if(m.containsKey(t[1])) + m.put(t[1], m.get(t[1]) + t[2]); + else + m.put(t[1], t[2]); + } + + List accnt = new ArrayList<>(); + for (Map.Entry a : m.entrySet()) { + if (a.getValue() != 0) accnt.add(a.getValue()); + } + return helper(accnt, 0, accnt.size(), 0); + } + + private int helper(List accnt, int start, int n, int num) { + int res = Integer.MAX_VALUE; + while (start < n && accnt.get(start) == 0) ++start; + for (int i = start + 1; i < n; ++i) { + if ((accnt.get(i) < 0 && accnt.get(start) > 0) || (accnt.get(i) > 0 && accnt.get(start) < 0)) { + accnt.set(i, accnt.get(i) + accnt.get(start)); // start set to 0 and update i + res = Math.min(res, helper(accnt, start + 1, n, num + 1)); + accnt.set(i, accnt.get(i) - accnt.get(start)); + } + } + return res == Integer.MAX_VALUE ? num : res; + } + + public static void main(String[] args) { + + OptimalAccountBalancing ob = new OptimalAccountBalancing(); + int[][] transactions = {{0,1,10}, {2,0,5}}; // {{0,1,10}, {1,0,1}, {1,2,5}, {2,0,5}}; + System.out.println(ob.minTransfers(transactions)); + + + } + + + + + +} diff --git a/src/main/java/output_contest_matches/OutputContestMatches.java b/src/main/java/output_contest_matches/OutputContestMatches.java new file mode 100644 index 0000000..b14c8e0 --- /dev/null +++ b/src/main/java/output_contest_matches/OutputContestMatches.java @@ -0,0 +1,34 @@ +package output_contest_matches; + +import java.util.Arrays; + +/** + * Created by lxie on 9/16/18. + */ +public class OutputContestMatches { + + public static class Solution { + + public String findContestMatch(int n) { + String[] v = new String[n+1]; Arrays.fill(v, ""); + for (int i = 1; i <= n; ++i) v[i-1] = Integer.toString(i); + helper(n, v); + return v[0]; + } + void helper(int n, String[] v) { + if (n == 1) return; + for (int i = 0; i < n; ++i) { + v[i] = "(" + v[i] + "," + v[n - i - 1] + ")"; + } + helper(n / 2, v); + } + + } + + public static void main(String[] args) { + Solution s = new Solution(); + String res = s.findContestMatch(8); + System.out.println(res); + + } +} diff --git a/src/main/java/pacific_atlantic_water_flow/OceanWaterFlow.java b/src/main/java/pacific_atlantic_water_flow/OceanWaterFlow.java new file mode 100644 index 0000000..9c3c7c2 --- /dev/null +++ b/src/main/java/pacific_atlantic_water_flow/OceanWaterFlow.java @@ -0,0 +1,56 @@ +package pacific_atlantic_water_flow; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by lxie on 8/21/18. + */ +public class OceanWaterFlow { + + public class Solution { + + public List pacificAtlantic(int[][] matrix) { + if (matrix.length == 0 || matrix[0].length == 0) return new ArrayList<>(); + List res = new ArrayList<>(); + int m = matrix.length, n = matrix[0].length; + boolean[][] pacific = new boolean[m][n]; + boolean[][] atlantic = new boolean[m][n]; + for (int i = 0; i < m; ++i) { + dfs(matrix, pacific, Integer.MIN_VALUE, i, 0); + dfs(matrix, atlantic, Integer.MIN_VALUE, i, n - 1); + } + for (int i = 0; i < n; ++i) { + dfs(matrix, pacific, Integer.MIN_VALUE, 0, i); + dfs(matrix, atlantic, Integer.MIN_VALUE, m - 1, i); + } + for (int i = 0; i < m; ++i) { + for (int j = 0; j < n; ++j) { + if (pacific[i][j] && atlantic[i][j]) { + int[] out = {i, j}; + res.add(out); + } + } + } + return res; + } + void dfs(int[][] matrix, boolean[][] visited, int pre, int i, int j) { + int m = matrix.length, n = matrix[0].length; + if (i < 0 || i >= m || j < 0 || j >= n || visited[i][j] || matrix[i][j] < pre) return; + visited[i][j] = true; + dfs(matrix, visited, matrix[i][j], i + 1, j); + dfs(matrix, visited, matrix[i][j], i - 1, j); + dfs(matrix, visited, matrix[i][j], i, j + 1); + dfs(matrix, visited, matrix[i][j], i, j - 1); + } + + + } + + public class UnitTest { + + + + } + +} diff --git a/src/main/java/paint_house/PaintHouse.java b/src/main/java/paint_house/PaintHouse.java new file mode 100644 index 0000000..d765a42 --- /dev/null +++ b/src/main/java/paint_house/PaintHouse.java @@ -0,0 +1,29 @@ +package paint_house; + +/** + * Created by lxie on 6/3/18. + */ +public class PaintHouse { + + public static class Solution { + + int minCost(int [][] costs) { + if (costs.length == 0 || costs[0].length == 0) return 0; + int[][] dp = costs; + for (int i = 1; i < dp.length; ++i) { + for (int j = 0; j < 3; ++j) { + dp[i][j] += Integer.min(dp[i - 1][(j + 1) % 3], dp[i - 1][(j + 2) % 3]); + } + } + int n = dp.length; + return Integer.min(Integer.min(dp[n-1][0], dp[n-1][1]), dp[n-1][2]); + } + } + + public static void main(String[] args) { + Solution sol = new Solution(); + int[][] costs= {{1, 2, 3, 4, 5}, {1, 2, 3, 4, 5}, {1, 2, 3, 4, 5}}; + int res = sol.minCost(costs); + System.out.println("result is "+res); + } +} diff --git a/src/main/java/paint_house_ii/PaintHouseII.java b/src/main/java/paint_house_ii/PaintHouseII.java new file mode 100644 index 0000000..dc6be8b --- /dev/null +++ b/src/main/java/paint_house_ii/PaintHouseII.java @@ -0,0 +1,41 @@ +package paint_house_ii; + +/** + * Created by lxie on 6/6/18. + */ +public class PaintHouseII { + + public class Solution { + + public int minCostII(int[][] costs) { + if (costs.length == 0 || costs[0].length == 0) return 0; + int[][] dp = costs; + int min1 = -1, min2 = -1; + for (int i = 0; i < dp.length; ++i) { + int last1 = min1, last2 = min2; + min1 = -1; min2 = -1; + for (int j = 0; j < dp[i].length; ++j) { + if (j != last1) { + dp[i][j] += last1 < 0 ? 0 : dp[i - 1][last1]; + } else { + dp[i][j] += last2 < 0 ? 0 : dp[i - 1][last2]; + } + if (min1 < 0 || dp[i][j] < dp[i][min1]) { + min2 = min1; min1 = j; + } else if (min2 < 0 || dp[i][j] < dp[i][min2]) { + min2 = j; + } + } + } + return dp[dp.length-1][min1]; + } + + + } + + public class UnitTest { + + + } + +} diff --git a/src/main/java/palindrom_pairs/PalindromePairs.java b/src/main/java/palindrom_pairs/PalindromePairs.java new file mode 100644 index 0000000..0e50fc9 --- /dev/null +++ b/src/main/java/palindrom_pairs/PalindromePairs.java @@ -0,0 +1,54 @@ +package palindrom_pairs; + +import java.util.*; + +/** + * Created by lxie on 1/23/18. + */ +public class PalindromePairs { + + public class Solution { + + public List> palindromePairs(String[] words) { + List> res = new ArrayList<>(); + Map m = new HashMap(); + Set s = new TreeSet(); + for (int i = 0; i < words.length; ++i) { + m.put(words[i], i); + s.add(words[i].length()); + } + for (int i = 0; i < words.length; ++i) { + String t = words[i]; + int len = t.length(); + t = new StringBuilder(t).reverse().toString(); + if (m.containsKey(t) && m.get(t) != i) { // not self + res.add(Arrays.asList(i, m.get(t))); + } + + for (int d : s) { + if (d >= len) break; + if (isValid(t, 0, len - d - 1) && m.containsKey(t.substring(len - d))) { + res.add(Arrays.asList(i, m.get(t.substring(len - d)))); // abcdd - cba, t is reversed + } + if (isValid(t, d, len - 1) && m.containsKey(t.substring(0, d))) { + res.add(Arrays.asList(m.get(t.substring(0, d)), i)); // aabcd - dcb, t is reversed + } + } + } + return res; + } + + private boolean isValid(String t, int left, int right) { + while (left < right) { + if (t.toCharArray()[left++] != t.toCharArray()[right--]) return false; + } + return true; + } + + } + + public static class UnitTest { + + } + +} diff --git a/src/main/java/palindrome_linked_list/PalindromeLinkedList.java b/src/main/java/palindrome_linked_list/PalindromeLinkedList.java new file mode 100644 index 0000000..56b5ea7 --- /dev/null +++ b/src/main/java/palindrome_linked_list/PalindromeLinkedList.java @@ -0,0 +1,31 @@ +package palindrome_linked_list; + +import common.ListNode; + +/** + * Created by lxie on 1/2/18. + */ +public class PalindromeLinkedList { + + public boolean isPalindrome(ListNode head) { + if (head == null || head.next == null) return true; + ListNode slow = head, fast = head; + while (fast.next != null && fast.next.next != null) { + slow = slow.next; + fast = fast.next.next; + } + ListNode last = slow.next, pre = head; + while (last.next != null) { + ListNode tmp = last.next; + last.next = tmp.next; + tmp.next = slow.next; + slow.next = tmp; + } + while (slow.next != null) { + slow = slow.next; + if (pre.val != slow.val) return false; + pre = pre.next; + } + return true; + } +} diff --git a/src/main/java/palindrome_number/PalindromeNumber.java b/src/main/java/palindrome_number/PalindromeNumber.java index 717ea24..3096f3b 100644 --- a/src/main/java/palindrome_number/PalindromeNumber.java +++ b/src/main/java/palindrome_number/PalindromeNumber.java @@ -4,22 +4,19 @@ public class PalindromeNumber { public class Solution { public boolean isPalindrome(int x) { - if (x == 0) { - return true; + if (x < 0) return false; + int div = 1; + while (x / div >= 10) div *= 10; + while (x > 0) { + int left = x / div; + int right = x % 10; + if (left != right) return false; + x = (x % div) / 10; + div /= 100; } - if (x < 0 || x % 10 == 0) { - return false; - } - int y = 0; - do { - if (y == x / 10 || y == x) { - return true; - } - y = y * 10 + x % 10; - x = x / 10; - } while (x > y); - return y == x; + return true; } + } public static class UnitTest { diff --git a/src/main/java/palindrome_partitioning/PalindromePartitioning.java b/src/main/java/palindrome_partitioning/PalindromePartitioning.java index d4a65a0..1633000 100644 --- a/src/main/java/palindrome_partitioning/PalindromePartitioning.java +++ b/src/main/java/palindrome_partitioning/PalindromePartitioning.java @@ -1,51 +1,46 @@ package palindrome_partitioning; import java.util.ArrayList; -import java.util.HashMap; -import java.util.Map; +import java.util.List; public class PalindromePartitioning { - public class Solution { - private boolean isPalindromic(String s) { - for (int i = 0; i < s.length() / 2; i++) { - if (s.charAt(i) != s.charAt(s.length() - 1 - i)) { - return false; - } - } - return true; - } + public static class Solution { - private Map>> cache = new HashMap>>(); + public List> partition(String s) { + List> res = new ArrayList<>(); + List out = new ArrayList<>(); + partitionDFS(s, 0, out, res); + return res; + } - public ArrayList> partition(String s) { - ArrayList> ans = cache.get(s); - if (ans != null) { - return ans; + public void partitionDFS(String s, int start, List out, List> res) { + if (start == s.length()) { + res.add(new ArrayList<>(out)); + return; } - ans = new ArrayList>(); - for (int i = 1; i < s.length(); i++) { - String prefix = s.substring(0, i); - if (isPalindromic(prefix)) { - for (ArrayList subans : partition(s.substring(i))) { - ArrayList temp = new ArrayList(); - temp.add(prefix); - temp.addAll(subans); - ans.add(temp); - } + for (int i = start; i < s.length(); ++i) { + if (isPalindrome(s, start, i)) { + out.add(s.substring(start, i+1)); + partitionDFS(s, i + 1, out, res); + out.remove(out.size()-1); } } - if (isPalindromic(s)) { - ArrayList temp = new ArrayList(); - temp.add(s); - ans.add(temp); + } + + private boolean isPalindrome(String s, int start, int end) { + while (start < end) { + if (s.charAt(start) != s.charAt(end)) return false; + ++start; + --end; } - cache.put(s, ans); - return ans; + return true; } - } - public static class UnitTest { + } + public static void main(String[] args) { + Solution sol = new Solution(); + System.out.println(sol.partition("aab")); } } diff --git a/src/main/java/palindrome_partitioning_ii/PalindromePartitioningII.java b/src/main/java/palindrome_partitioning_ii/PalindromePartitioningII.java index 0d5cdac..ee935c8 100644 --- a/src/main/java/palindrome_partitioning_ii/PalindromePartitioningII.java +++ b/src/main/java/palindrome_partitioning_ii/PalindromePartitioningII.java @@ -1,6 +1,5 @@ package palindrome_partitioning_ii; -import org.junit.Test; public class PalindromePartitioningII { @@ -16,7 +15,7 @@ public int minCut(String s) { cuts[i + 1] = i; } for (int i = 0; i < s.length(); i++) { - for (int j = i; j >= 0; j--) { + for (int j = 0; j <= i; j++) { if (s.charAt(i) == s.charAt(j) && (i - j < 2 || isPalindrome[j + 1][i - 1])) { isPalindrome[j][i] = true; @@ -29,10 +28,5 @@ public int minCut(String s) { } public static class UnitTest { - - @Test - public void test() { - new PalindromePartitioningII().new Solution().minCut("efe"); - } } } diff --git a/src/main/java/palindrome_permutation/PalindromePermutation.java b/src/main/java/palindrome_permutation/PalindromePermutation.java new file mode 100644 index 0000000..87d6e21 --- /dev/null +++ b/src/main/java/palindrome_permutation/PalindromePermutation.java @@ -0,0 +1,31 @@ +package palindrome_permutation; + +import java.util.HashMap; +import java.util.Map; + + +public class PalindromePermutation { + + public class Solution { + public boolean palindromePermutation(String s) { + Map m = new HashMap<>(); + int cnt = 0; + for (char a : s.toCharArray()) { + if(m.containsKey(a)) { + m.put(a, m.get(a)+1); + } else { + m.put(a, 1); + } + } + for (Map.Entry entry : m.entrySet()) { + if (entry.getValue() % 2 != 0) ++cnt; + } + return cnt == 0 || (s.length() % 2 == 1 && cnt == 1); + } + } + + public static class UnitTest { + + } + +} diff --git a/src/main/java/palindrome_permutation_ii/PalindromePermutationII.java b/src/main/java/palindrome_permutation_ii/PalindromePermutationII.java new file mode 100644 index 0000000..42c48a8 --- /dev/null +++ b/src/main/java/palindrome_permutation_ii/PalindromePermutationII.java @@ -0,0 +1,58 @@ +package palindrome_permutation_ii; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class PalindromePermutationII { + + public class Solution { + + public List generatePalindrome(String s) { + List res = new ArrayList<>(); + Map m = new HashMap<>(); + String t = "", mid = ""; + for (Character a : s.toCharArray()) { + if (m.containsKey(a)) { + m.put(a, m.get(a) + 1); + } else { + m.put(a, 1); + } + } + for (Map.Entry e : m.entrySet()) { + if (e.getValue() % 2 == 1) mid += e.getKey(); + t += new String(new char[e.getValue() / 2]).replace("\0", e.getKey().toString()); + if (mid.length() > 1) return res; + } + permute(t, 0, mid, res); + return res; + } + + public void permute(String t, int start, String mid, List res) { + if (start >= t.length()) { + res.add(t + mid + new StringBuffer(t).reverse()); + } + for (int i = start; i < t.length(); ++i){ + if (i != start && t.charAt(i) == t.charAt(start)) continue; + swap(t, i, start); //t.charAt(i), t.charAt(start)); + permute(t, start+1, mid, res); + swap(t, i, start); //.charAt(i), t.charAt(start)); + } + } + + private String swap(String s, int a, int b) { + char[] chars = s.toCharArray(); + char tmp = chars[a]; + chars[a] = chars[b]; + chars[b] = tmp; + return new String(chars); + } + + } + + public static class UnitTest { + + } + +} diff --git a/src/main/java/palindromic_substring/PalindromicSubstring.java b/src/main/java/palindromic_substring/PalindromicSubstring.java new file mode 100644 index 0000000..dd25bce --- /dev/null +++ b/src/main/java/palindromic_substring/PalindromicSubstring.java @@ -0,0 +1,27 @@ +package palindromic_substring; + +/** + * Created by lxie on 9/30/18. + */ +public class PalindromicSubstring { + + public class Solution { + + public int countSubstrings(String s) { + int n = s.length(), res = 0; + boolean[][] dp = new boolean[n][n]; + for (int i = n - 1; i >= 0; --i) { + for (int j = i; j < n; ++j) { + dp[i][j] = s.charAt(i) == s.charAt(j) && (j - i <= 2 || dp[i + 1][j - 1]); + if (dp[i][j]) ++res; + } + } + return res; + } + } + + public class UnitTest { + + } + +} diff --git a/src/main/java/partition_list/PartitionList.java b/src/main/java/partition_list/PartitionList.java index ad7ab3d..6804117 100644 --- a/src/main/java/partition_list/PartitionList.java +++ b/src/main/java/partition_list/PartitionList.java @@ -5,42 +5,25 @@ public class PartitionList { public class Solution { - public ListNode partition(ListNode head, int x) { - ListNode lessHead = null; - ListNode lessTail = null; - ListNode greaterHead = null; - ListNode greaterTail = null; - ListNode p = head; - while (p != null) { - if (p.val < x) { - if (lessHead == null) { - lessHead = p; - } else { - lessTail.next = p; - } - lessTail = p; + ListNode partition(ListNode head, int x) { + if (head == null) return head; + ListNode dummy = new ListNode(-1); + ListNode newDummy = new ListNode(-1); + + dummy.next = head; + ListNode cur = dummy, p = newDummy; + while (cur.next != null) { + if (cur.next.val < x) { + p.next = cur.next; + p = p.next; + cur.next = cur.next.next; + p.next = null; } else { - if (greaterHead == null) { - greaterHead = p; - } else { - greaterTail.next = p; - } - greaterTail = p; - } - p = p.next; - } - if (lessHead == null) { - if (greaterTail != null) { - greaterTail.next = null; - } - return greaterHead; - } else { - lessTail.next = greaterHead; - if (greaterTail != null) { - greaterTail.next = null; + cur = cur.next; } - return lessHead; } + p.next = dummy.next; + return newDummy.next; } } diff --git a/src/main/java/patching_array/PatchingArray.java b/src/main/java/patching_array/PatchingArray.java new file mode 100644 index 0000000..85ba98e --- /dev/null +++ b/src/main/java/patching_array/PatchingArray.java @@ -0,0 +1,33 @@ +package patching_array; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +/** + * Created by lxie on 9/15/18. + */ +public class PatchingArray { + + public class Solution { + + public int minPatches(int[] nums, int n) { + long miss = 1, k = nums.length; + long[] longArray = Arrays.stream(nums).mapToLong(i -> i).toArray(); + List nums1 = Arrays.stream(longArray).boxed().collect(Collectors.toList()) ; + int i = 0; + while (miss <= n) { + if (i >= nums1.size() || nums1.get(i) > miss) { + nums1.add(i, miss); + } + miss += nums1.get(i++); + } + return (int) (nums1.size() - k); + } + } + + public class UnitTest { + + } + +} diff --git a/src/main/java/path_sum_ii/PathSumII.java b/src/main/java/path_sum_ii/PathSumII.java index 43af93b..a58c93c 100644 --- a/src/main/java/path_sum_ii/PathSumII.java +++ b/src/main/java/path_sum_ii/PathSumII.java @@ -1,39 +1,32 @@ package path_sum_ii; -import java.util.ArrayList; - import common.TreeNode; +import java.util.ArrayList; +import java.util.List; + public class PathSumII { public class Solution { - public ArrayList> pathSum(TreeNode root, int sum) { - ArrayList> ans = new ArrayList>(); - if (root != null) { - pathSum(root, sum, new ArrayList(), ans); - } - return ans; + + public List> pathSum(TreeNode root, int sum) { + List> res = new ArrayList<>(); + List out = new ArrayList<>(); + helper(root, sum, out, res); + return res; } - private void pathSum(TreeNode root, int sum, ArrayList nodes, - ArrayList> ans) { - if (root.left == null && root.right == null) { - if (root.val == sum) { - ArrayList temp = new ArrayList(nodes); - temp.add(root.val); - ans.add(temp); - } - return; - } - nodes.add(root.val); - if (root.left != null) { - pathSum(root.left, sum - root.val, nodes, ans); + private void helper(TreeNode node, int sum, List out, List> res) { + if (node == null) return; + out.add(node.val); + if (sum == node.val && node.left == null && node.right == null) { + res.add(new ArrayList<>(out)); // do not use the same reference } - if (root.right != null) { - pathSum(root.right, sum - root.val, nodes, ans); - } - nodes.remove(nodes.size() - 1); + helper(node.left, sum - node.val, out, res); + helper(node.right, sum - node.val, out, res); + out.remove(out.size()-1); // back-track to remove current } + } public static class UnitTest { diff --git a/src/main/java/peeking_iterator/PeekIterator.java b/src/main/java/peeking_iterator/PeekIterator.java new file mode 100644 index 0000000..48f68b0 --- /dev/null +++ b/src/main/java/peeking_iterator/PeekIterator.java @@ -0,0 +1,49 @@ +package peeking_iterator; + +import java.util.Iterator; + +/** + * Created by lxie on 6/15/18. + */ +//Java Iterator interface reference: +// https://docs.oracle.com/javase/8/docs/api/java/util/Iterator.html +class PeekingIterator implements Iterator { + + private static int _value; + private static boolean _flag; + private final Iterator _iterator; + + + public PeekingIterator(Iterator iterator) { + // initialize any member here. + _iterator = iterator; + _flag = false; + } + + // Returns the next element in the iteration without advancing the iterator. + public Integer peek() { + if (!_flag) { + _value = _iterator.next(); + _flag = true; + } + return _value; + + } + + // hasNext() and next() should behave the same as in the Iterator interface. + // Override them if needed. + @Override + public Integer next() { + if (!_flag) return _iterator.next(); + _flag = false; + return _value; + } + + @Override + public boolean hasNext() { + if (_flag) return true; + if (_iterator.hasNext()) return true; + return false; + + } +} diff --git a/src/main/java/perfect_rectangle/PerfectRectangle.java b/src/main/java/perfect_rectangle/PerfectRectangle.java new file mode 100644 index 0000000..083f4ab --- /dev/null +++ b/src/main/java/perfect_rectangle/PerfectRectangle.java @@ -0,0 +1,53 @@ +package perfect_rectangle; + +import java.util.HashMap; +import java.util.Map; + +/** + * Created by lxie on 8/22/18. + */ +public class PerfectRectangle { + + public class Solution { + public boolean isRectangleCover(int[][] rectangles) { + Map m = new HashMap<>(); + int min_x = Integer.MAX_VALUE, min_y = Integer.MAX_VALUE, + max_x = Integer.MIN_VALUE, max_y = Integer.MIN_VALUE, area = 0, cnt = 0; + for (int[] rect : rectangles) { + min_x = Math.min(min_x, rect[0]); + min_y = Math.min(min_y, rect[1]); + max_x = Math.max(max_x, rect[2]); + max_y = Math.max(max_y, rect[3]); + area += (rect[2] - rect[0]) * (rect[3] - rect[1]); + if (!isValid(m, Integer.toString(rect[0]) + "_" + Integer.toString(rect[1]), 1)) return false; // bottom-left + if (!isValid(m, Integer.toString(rect[0]) + "_" + Integer.toString(rect[3]), 2)) return false; // top-left + if (!isValid(m, Integer.toString(rect[2]) + "_" + Integer.toString(rect[3]), 4)) return false; // top-right + if (!isValid(m, Integer.toString(rect[2]) + "_" + Integer.toString(rect[1]), 8)) return false; // bottom-right + } + for (Map.Entry it : m.entrySet() ) { + int t = it.getValue(); + if (t != 15 && t != 12 && t != 10 && t != 9 && t != 6 && t != 5 && t!= 3) { + ++cnt; + } + } + return cnt == 4 && area == (max_x - min_x) * (max_y - min_y); + } + + private boolean isValid(Map m, String corner, int type) { + int val = 0; + if (m.containsKey(corner)) val = m.get(corner); + if ((val & type) != 0) return false; // cannot be same type of corner twice + m.put(corner, val|type); + return true; + } + + + } + + public class UnitTest { + + + + } + +} diff --git a/src/main/java/perfect_squares/PerfectSquares.java b/src/main/java/perfect_squares/PerfectSquares.java new file mode 100644 index 0000000..a1fa2eb --- /dev/null +++ b/src/main/java/perfect_squares/PerfectSquares.java @@ -0,0 +1,22 @@ +package perfect_squares; + +/** + * Created by lxie on 1/8/18. + */ +public class PerfectSquares { + + public class Solution { + public int numSquares(int n) { + int[] dp = new int[n+1]; + for (int i=0; i= num[--j]) { + } + swap(num, i, j); + reverse(num, i + 1, num.length); + return true; + } + if (i == 0) { + reverse(num, 0, num.length); + return false; + } + } + } + + public ArrayList> permute(int[] num) { + Arrays.sort(num); + ArrayList> ans = new ArrayList>(); + do { + ArrayList l = new ArrayList(); + for (int n : num) { + l.add(n); + } + ans.add(l); + } while (nextPermutation(num)); + return ans; + } + } + + public static class UnitTest { + + } +} diff --git a/src/main/java/permutations_ii/PermutationsII.java b/src/main/java/permutations_ii/PermutationsII.java new file mode 100644 index 0000000..0bf67da --- /dev/null +++ b/src/main/java/permutations_ii/PermutationsII.java @@ -0,0 +1,37 @@ +package permutations_ii; + +import java.util.*; +import java.util.stream.Collectors; + +public class PermutationsII { + + public class Solution { + public List> permuteUnique(int[] nums) { + Set> res = new HashSet<>(); + permute(nums, 0, res); + return new ArrayList<>(res); + } + + private void permute(int[] nums, int start, Set> res) { + if (start >= nums.length) + res.add(Arrays.stream(nums).boxed().collect(Collectors.toList())); + for (int i = start; i < nums.length; ++i) { + if (i != start && nums[i] == nums[start]) continue; + swap(nums, i, start); + permute(nums, start + 1, res); + swap(nums, i, start); + } + } + + private void swap(int[] num, int i, int j) { + int temp = num[i]; + num[i] = num[j]; + num[j] = temp; + } + + } + + public static class UnitTest { + + } +} diff --git a/src/main/java/plus_one_linked_list/PlusOneLinkedList.java b/src/main/java/plus_one_linked_list/PlusOneLinkedList.java new file mode 100644 index 0000000..d413e2c --- /dev/null +++ b/src/main/java/plus_one_linked_list/PlusOneLinkedList.java @@ -0,0 +1,44 @@ +package plus_one_linked_list; + +/** + * Created by lxie on 10/1/17. + */ +public class PlusOneLinkedList { + + /** + * Definition for singly-linked list. + **/ + public class ListNode { + int val; + ListNode next; + ListNode(int x) { val = x; } + } + + class Solution { + public ListNode PlusOneLinkedList(ListNode head) { + if (head == null) return head; + int carry = helper(head); + if (carry == 1) { + ListNode res = new ListNode(1); + res.next = head; + return res; + } + return head; + } + + int helper(ListNode node) { + if (node == null) return 1; + int carry = helper(node.next); + int sum = node.val + carry; + node.val = sum % 10; + return sum/10; + } + + } + + public static class UnitTest { + + } + + +} diff --git a/src/main/java/populating_next_right_pointers_in_each_node_ii/PopulatingNextRightPointersinEachNodeII.java b/src/main/java/populating_next_right_pointers_in_each_node_ii/PopulatingNextRightPointersinEachNodeII.java new file mode 100644 index 0000000..9c9987f --- /dev/null +++ b/src/main/java/populating_next_right_pointers_in_each_node_ii/PopulatingNextRightPointersinEachNodeII.java @@ -0,0 +1,33 @@ +package populating_next_right_pointers_in_each_node_ii; + +import common.TreeLinkNode; + +public class PopulatingNextRightPointersinEachNodeII { + + public class Solution { // const space + public void connect(TreeLinkNode root) { + TreeLinkNode dummy = new TreeLinkNode(0), t = dummy; + while (root != null) { + if (root.left != null) { + t.next = root.left; + t = t.next; + } + if (root.right != null) { + t.next = root.right; + t = t.next; + } + root = root.next; + if (root == null) { + t = dummy; + root = dummy.next; + dummy.next = null; + } + } + } + + } + + public static class UnitTest { + + } +} diff --git a/src/main/java/pow_x_n/Powxn.java b/src/main/java/pow_x_n/Powxn.java index 9392856..5a48815 100644 --- a/src/main/java/pow_x_n/Powxn.java +++ b/src/main/java/pow_x_n/Powxn.java @@ -3,29 +3,18 @@ public class Powxn { public class Solution { - public double pow(double x, int n) { - boolean overflow = false; - if (n == Integer.MIN_VALUE) { - overflow = true; - n++; - } - boolean negative = n < 0; - n = Math.abs(n); - double re = 1; - double times = x; - while (n != 0) { - if ((n & 1) == 1) { - re *= times; - } - times *= times; - n >>= 1; - } - if (negative) { - return overflow ? 1 / (re * x) : 1 / re; - } else { - return re; - } + public double myPow(double x, int n) { + if (n < 0) return 1 / power(x, -n); + return power(x, n); } + + private double power(double x, int n) { + if (n == 0) return 1; + double half = power(x, n / 2); + if (n % 2 == 0) return half * half; + return x * half * half; + } + } public static class UnitTest { diff --git a/src/main/java/predict_the_winner/PredictTheWinner.java b/src/main/java/predict_the_winner/PredictTheWinner.java new file mode 100644 index 0000000..49490f9 --- /dev/null +++ b/src/main/java/predict_the_winner/PredictTheWinner.java @@ -0,0 +1,33 @@ +package predict_the_winner; + +import java.util.Arrays; + +/** + * Created by lxie on 9/4/18. + */ +public class PredictTheWinner { + + public class Solution { + + public boolean PredictTheWinner(int[] nums) { + int n = nums.length; + int[][] dp = new int[n][n]; + for(int[] a : dp) Arrays.fill(a, -1); + return canWin(nums, 0, n - 1, dp) >= 0; + } + + private int canWin(int[] nums, int s, int e, int[][] dp) { + if (dp[s][e] == -1) { + dp[s][e] = (s == e) ? nums[s] : + Math.max(nums[s] - canWin(nums, s + 1, e, dp), nums[e] - canWin(nums, s, e - 1, dp)); + } + return dp[s][e]; + } + + } + + public class UnitTest { + + + } +} diff --git a/src/main/java/product_array_except_self/ProductArrayExceptSelf.java b/src/main/java/product_array_except_self/ProductArrayExceptSelf.java new file mode 100644 index 0000000..a1bd7ad --- /dev/null +++ b/src/main/java/product_array_except_self/ProductArrayExceptSelf.java @@ -0,0 +1,29 @@ +package product_array_except_self; + +/** + * Created by lxie on 12/11/17. + */ +public class ProductArrayExceptSelf { + + public class Solution { + public int[] productExceptSelf(int[] nums) { + int[] res = new int[nums.length]; + for (int i = 0; i < nums.length; ++i) res[i] = 1; + for (int i = 1; i < nums.length; ++i) { + res[i] = res[i-1] * nums[i-1]; + } + int right = 1; + for (int i = nums.length - 1; i >= 0; --i) { + res[i] *= right; + right *= nums[i]; + } + return res; + + } + } + + public static class UnitTest { + + } + +} diff --git a/src/main/java/queue_reconstruct_by_height/QueueReconsByHeight.java b/src/main/java/queue_reconstruct_by_height/QueueReconsByHeight.java new file mode 100644 index 0000000..6e168e8 --- /dev/null +++ b/src/main/java/queue_reconstruct_by_height/QueueReconsByHeight.java @@ -0,0 +1,43 @@ +package queue_reconstruct_by_height; + +import java.util.*; + +/** + * Created by lxie on 9/17/17. + */ +public class QueueReconsByHeight { + + public static class Solution { + public int[][] reconstructQueue(int[][] people) { + List peopleL = new LinkedList(Arrays.asList(people)); + Collections.sort(peopleL, new Comparator(){ + public int compare(int[] arr1, int[] arr2){ + if(arr1[0] == arr2[0]) + return arr1[1] - arr2[1]; + else + return arr2[0] - arr1[0]; + } + }); + + for (int i = 0; i < peopleL.size(); i++) { + int[] p = peopleL.get(i); + if (p[1] != i) { + peopleL.remove(i); + peopleL.add(p[1], p); // (idx, element) + } + } + + return peopleL.toArray(new int[peopleL.size()][2]); + } + + } + + public static void main(String[] args) { + System.out.println("this is for test"); + Solution sol = new Solution(); + int[][] people = {{7,0}, {4,4}, {7,1}, {5,0}, {6,1}, {5,2}}; + int[][] res = sol.reconstructQueue(people); + System.out.println(res.toString()); + } + +} diff --git a/src/main/java/range_addition/RangeAddition.java b/src/main/java/range_addition/RangeAddition.java new file mode 100644 index 0000000..4623239 --- /dev/null +++ b/src/main/java/range_addition/RangeAddition.java @@ -0,0 +1,36 @@ +package range_addition; + +/** + * Created by lxie on 7/23/18. + */ +public class RangeAddition { + + public class Solution { + + public int[] getModifiedArray(int length, int[][] updates) { + // Write your code here + int add[] = new int[length + 1]; + int res[] = new int[length]; + for(int i = 0; i < updates.length; i++){ + int first = updates[i][0]; + int second = updates[i][1]; + int third = updates[i][2]; + + add[first] += third; + add[second + 1] -= third; + } + res[0] = add[0]; + for(int i = 1; i < res.length; i++){ + res[i] = add[i] + res[i - 1]; + } + + return res; + } + + } + + public class UnitTest { + + } + +} diff --git a/src/main/java/range_sum_query_2d/NumMatrix.java b/src/main/java/range_sum_query_2d/NumMatrix.java new file mode 100644 index 0000000..7e2bc1d --- /dev/null +++ b/src/main/java/range_sum_query_2d/NumMatrix.java @@ -0,0 +1,23 @@ +package range_sum_query_2d; + +/** + * Created by lxie on 6/28/18. + */ +public class NumMatrix { + + private int[][] dp = null; + + public NumMatrix(int[][] matrix) { + if (matrix.length == 0 || matrix[0].length == 0) return; + dp = new int[matrix.length+1][matrix[0].length+1]; + for (int i = 1; i <= matrix.length; ++i) { + for (int j = 1; j <= matrix[0].length; ++j) { + dp[i][j] = dp[i][j - 1] + dp[i - 1][j] - dp[i - 1][j - 1] + matrix[i - 1][j - 1]; + } + } + } + + public int sumRegion(int row1, int col1, int row2, int col2) { + return dp[row2 + 1][col2 + 1] - dp[row1][col2 + 1] - dp[row2 + 1][col1] + dp[row1][col1]; + } +} diff --git a/src/main/java/rearrange_string_k_distance/RearrangeStringKDistance.java b/src/main/java/rearrange_string_k_distance/RearrangeStringKDistance.java new file mode 100644 index 0000000..a007684 --- /dev/null +++ b/src/main/java/rearrange_string_k_distance/RearrangeStringKDistance.java @@ -0,0 +1,48 @@ +package rearrange_string_k_distance; + +import common.Pair; + +import java.util.*; + +/** + * Created by lxie on 12/9/17. + */ +public class RearrangeStringKDistance { + public static class Solution { + public String RearrangeString(String str, int k) { + if (k == 0) return str; + String res = ""; + int len = str.length(); + Map m = new HashMap<>(); + PriorityQueue> q = new PriorityQueue<>(); + for (char a : str.toCharArray()) { + if (!m.containsKey(a)) m.put(a, 1); + else + m.put(a, m.get(a)+1); + }; + for (Map.Entry entry : m.entrySet()) { + q.add(Pair.of(entry.getValue(), entry.getKey())); + } + while (!q.isEmpty()) { + List> v = new ArrayList<>(); // for temp store + int cnt = Integer.min(k, len); + for (int i = 0; i < cnt; ++i) { + if (q.isEmpty()) return ""; + Map.Entry t = q.peek(); q.poll(); // highest count first + res += t.getValue(); + int count = t.getKey(); + if (--count > 0) v.add(t); + --len; + } + for (Map.Entry a : v) q.add(a); + } + return res; + + } + } + + public static class UnitTest { + + } + +} diff --git a/src/main/java/reconstruct_itinerary/findItinerary.java b/src/main/java/reconstruct_itinerary/findItinerary.java new file mode 100644 index 0000000..ebd2911 --- /dev/null +++ b/src/main/java/reconstruct_itinerary/findItinerary.java @@ -0,0 +1,48 @@ +package reconstruct_itinerary; + +import com.google.common.collect.TreeMultiset; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; + +/** + * Created by lxie on 9/16/17. + */ +public class findItinerary { + + public static class Solution { + public List findItinerary(String[][] tickets) { + List res = new ArrayList<>(); + HashMap> m = new HashMap<>(); + for (String[] a : tickets) { + if(m.get(a[0]) == null) { + m.put(a[0], TreeMultiset.create()); + } + m.get(a[0]).add(a[1]); + } + dfs(m, "JFK", res); + Collections.reverse(res); + return res; + } + + private void dfs(HashMap> m, String s, List res) { + while (m.get(s) != null && m.get(s).size() != 0) { + String t = m.get(s).firstEntry().toString(); + m.get(s).remove(t); + dfs(m, t, res); + } + res.add(s); + } + } + + public static void main(String[] args) { + System.out.println("this is for test"); + Solution sol = new Solution(); + String[][] tickets = {{"JFK", "KUL"}, {"JFK", "NRT"}, {"NRT", "JFK"}}; + List res = sol.findItinerary(tickets); + System.out.println(res.toString()); + } + +} diff --git a/src/main/java/recover_binary_search_tree/RecoverBinarySearchTree.java b/src/main/java/recover_binary_search_tree/RecoverBinarySearchTree.java index d0cb0f8..4ee1f74 100644 --- a/src/main/java/recover_binary_search_tree/RecoverBinarySearchTree.java +++ b/src/main/java/recover_binary_search_tree/RecoverBinarySearchTree.java @@ -4,50 +4,44 @@ public class RecoverBinarySearchTree { - public class Solution { + public class Solution { // O(1) space public void recoverTree(TreeNode root) { - TreeNode first = null; - TreeNode second = null; - TreeNode p = root; - TreeNode pre = null; - while (p != null) { - if (p.left == null) { - if (pre != null && pre.val > p.val) { - if (first == null) { - first = pre; - second = p; - } else { - second = p; - } + TreeNode first = null, second = null, parent = null; + TreeNode cur, pre; + cur = root; + while (cur != null) { + if (cur.left == null) { + if (parent != null && parent.val > cur.val) { + if (first == null) first = parent; + second = cur; } - pre = p; - p = p.right; + parent = cur; + cur = cur.right; } else { - TreeNode temp = p.left; - while (temp.right != null && temp.right != p) { - temp = temp.right; - } - if (temp.right == null) { - temp.right = p; - p = p.left; + pre = cur.left; + while (pre.right != null && pre.right != cur) pre = pre.right; + if (pre.right == null) { + pre.right = cur; + cur = cur.left; } else { - if (pre != null && pre.val > p.val) { - if (first == null) { - first = pre; - second = p; - } else { - second = p; - } + pre.right = null; + if (parent.val > cur.val) { + if (first == null) first = parent; + second = cur; } - temp.right = null; - pre = p; - p = p.right; + parent = cur; + cur = cur.right; } } } - int temp = first.val; - first.val = second.val; - second.val = temp; + if (first != null && second != null) swap(first, second); + } + + + private void swap(TreeNode first, TreeNode second) { + int temp = second.val; + second.val = first.val; + first.val = temp; } } diff --git a/src/main/java/redundant_connection/RedundantConnection.java b/src/main/java/redundant_connection/RedundantConnection.java new file mode 100644 index 0000000..233f3dc --- /dev/null +++ b/src/main/java/redundant_connection/RedundantConnection.java @@ -0,0 +1,33 @@ +package redundant_connection; + +import java.util.Arrays; + +/** + * Created by lxie on 8/27/18. + */ +public class RedundantConnection { + + public class Solution { + public int[] findRedundantDirectedConnection(int[][] edges) { + int[] root = new int[2001]; + Arrays.fill(root, -1); + for (int[] edge : edges) { + int x = find(root, edge[0]), y = find(root, edge[1]); + if (x == y) return edge; + root[x] = y; + } + return null; + } + int find(int[] root, int i) { + while (root[i] != -1) { + i = root[i]; + } + return i; + } + } + + public class UnitTest { + + } + +} diff --git a/src/main/java/redundant_connection_ii/RedundantConnectionII.java b/src/main/java/redundant_connection_ii/RedundantConnectionII.java new file mode 100644 index 0000000..dbf8f11 --- /dev/null +++ b/src/main/java/redundant_connection_ii/RedundantConnectionII.java @@ -0,0 +1,45 @@ +package redundant_connection_ii; + +/** + * Created by lxie on 9/11/18. + */ +public class RedundantConnectionII { + + public class Solution { + + public int[] findRedundantDirectedConnection(int[][] edges) { + int n = edges.length; + int[] root = new int[n+1]; + int[] first = new int[2], second = new int[2]; + for (int[] edge : edges) { + if (root[edge[1]] == 0) { + root[edge[1]] = edge[0]; + } else { + first[0] = root[edge[1]]; first[1] = edge[1]; + second[0] = edge[0]; second[1] = edge[1]; + edge[1] = 0; + } + } + for (int i = 0; i <= n; ++i) root[i] = i; + for (int[] edge : edges) { + if (edge[1] == 0) continue; + int x = getRoot(root, edge[0]), y = getRoot(root, edge[1]); + if (x == y) return first[0] == 0 ? edge : first; + root[x] = y; + } + return second; + } + + private int getRoot(int[] root, int i) { + return i == root[i] ? i : getRoot(root, root[i]); + } + + + } + + public class UnitTest { + + + } + +} diff --git a/src/main/java/regular_expression_matching/RegularExpressionMatching.java b/src/main/java/regular_expression_matching/RegularExpressionMatching.java new file mode 100644 index 0000000..a3c1739 --- /dev/null +++ b/src/main/java/regular_expression_matching/RegularExpressionMatching.java @@ -0,0 +1,29 @@ +package regular_expression_matching; + + +public class RegularExpressionMatching { + + public class Solution { + public boolean isMatch(String s, String p) { + if (p.isEmpty()) return s.isEmpty(); + if (p.length() == 1) { + return (s.length() == 1 && (s.charAt(0) == p.charAt(0) || + p.charAt(0) == '.')); + } + if (p.charAt(1) != '*') { + if (s.isEmpty()) return false; + return (s.charAt(0) == p.charAt(0) || p.charAt(0) == '.') && + isMatch(s.substring(1), p.substring(1)); + } + while (!s.isEmpty() && (s.charAt(0) == p.charAt(0) || p.charAt(0) == '.')) { + if (isMatch(s, p.substring(2))) return true; + s = s.substring(1); + } + return isMatch(s, p.substring(2)); + } + + } + + public static class UnitTest { + } +} diff --git a/src/main/java/relative_ranks/RelativeRanks.java b/src/main/java/relative_ranks/RelativeRanks.java new file mode 100644 index 0000000..6dbda66 --- /dev/null +++ b/src/main/java/relative_ranks/RelativeRanks.java @@ -0,0 +1,46 @@ +package relative_ranks; + +import common.Pair; + +import java.util.Comparator; +import java.util.Map; +import java.util.PriorityQueue; + +/** + * Created by lxie on 7/12/18. + */ +public class RelativeRanks { + + public class Solution { + + public String[] findRelativeRanks(int[] nums) { + int n = nums.length, cnt = 1; + String[] res = new String[n]; + PriorityQueue> q = + new PriorityQueue>(10, + new Comparator>() { + @Override + public int compare(Map.Entry p1, Map.Entry p2) { + return p2.getKey() - p1.getKey(); + } + }); + for (int i = 0; i < n; ++i) { + q.add(Pair.of(nums[i], i)); + } + for (int i = 0; i < n; ++i) { + int idx = q.peek().getValue(); q.poll(); + if (cnt == 1) res[idx] = "Gold Medal"; + else if (cnt == 2) res[idx] = "Silver Medal"; + else if (cnt == 3) res[idx] = "Bronze Medal"; + else res[idx] = Integer.toString(cnt); + ++cnt; + } + return res; + } + + } + + public class UnitTest { + + } +} diff --git a/src/main/java/remove_duplicate_letters/RemoveDuplicateLetters.java b/src/main/java/remove_duplicate_letters/RemoveDuplicateLetters.java new file mode 100644 index 0000000..a2f9b88 --- /dev/null +++ b/src/main/java/remove_duplicate_letters/RemoveDuplicateLetters.java @@ -0,0 +1,34 @@ +package remove_duplicate_letters; + +/** + * Created by lxie on 11/17/17. + */ +public class RemoveDuplicateLetters { + + public class Solution { + public String removeDuplicateLetters(String s) { + int[] m = new int[256]; + int[] visited = new int[256]; + String res = "0"; + for (char a : s.toCharArray()) { + ++m[a]; + } + for (char a : s.toCharArray()) { + --m[a]; + if (visited[a] != 0) continue; + while (a < res.charAt(res.length()-1) && m[res.charAt(res.length()-1)] != 0) { + visited[res.charAt(res.length()-1)] = 0; + res = res.substring(0, res.length()-1); + } + res += a; + visited[a] = 1; + } + return res.substring(1); + } + + } + + public static class UnitTest { + + } +} diff --git a/src/main/java/remove_duplicates_from_sorted_list_ii/RemoveDuplicatesfromSortedListII.java b/src/main/java/remove_duplicates_from_sorted_list_ii/RemoveDuplicatesfromSortedListII.java index e524ac4..e3050ef 100644 --- a/src/main/java/remove_duplicates_from_sorted_list_ii/RemoveDuplicatesfromSortedListII.java +++ b/src/main/java/remove_duplicates_from_sorted_list_ii/RemoveDuplicatesfromSortedListII.java @@ -6,41 +6,20 @@ public class RemoveDuplicatesfromSortedListII { public class Solution { public ListNode deleteDuplicates(ListNode head) { - if (head == null) { - return null; - } - ListNode pre = null; - int count = 1; - ListNode p = head; - while (p.next != null) { - if (p.next.val == p.val) { - count++; - } else if (count == 1) { - if (pre == null) { - head = p; - } - pre = p; - } else { - if (pre != null) { - pre.next = p.next; - } - count = 1; - } - p = p.next; - } - if (count == 1) { - if (pre == null) { - return p; - } else { - return head; - } - } - if (pre == null) { - return null; + if (head == null || head.next == null) return head; + + ListNode start = new ListNode(0); + start.next = head; + ListNode pre = start; + while (pre.next != null) { + ListNode cur = pre.next; + while (cur.next != null && cur.next.val == cur.val) cur = cur.next; + if (cur != pre.next) pre.next = cur.next; // need to delete nodes + else pre = pre.next; } - pre.next = null; - return head; + return start.next; } + } public static class UnitTest { diff --git a/src/main/java/remove_invalid_parentheses/RemoveInvalidParentheses.java b/src/main/java/remove_invalid_parentheses/RemoveInvalidParentheses.java new file mode 100644 index 0000000..018cb18 --- /dev/null +++ b/src/main/java/remove_invalid_parentheses/RemoveInvalidParentheses.java @@ -0,0 +1,53 @@ +package remove_invalid_parentheses; + +import java.util.*; + +/** + * Created by lxie on 6/23/18. + */ +public class RemoveInvalidParentheses { + + public class Solution { + + public List removeInvalidParentheses(String s) { + List res = new ArrayList<>(); + Set visited = new HashSet<>(); + Queue q = new LinkedList<>(); + q.add(s); + boolean found = false; + while (!q.isEmpty()) { + String t = q.peek(); q.poll(); + if (isValid(t)) { + res.add(t); + found = true; + } + if (found) continue; + for (int i = 0; i < t.length(); ++i) { + if (t.charAt(i) != '(' && t.charAt(i) != ')') continue; + String str = t.substring(0, i) + t.substring(i + 1); + if (!visited.contains(str)) { + q.add(str); + visited.add(str); + } + } + } + return res; + } + + boolean isValid(String t) { + int cnt = 0; + for (int i = 0; i < t.length(); ++i) { + if (t.charAt(i) == '(') ++cnt; + else if (t.charAt(i) == ')' && --cnt < 0) return false; + } + return cnt == 0; + } + + } + + public class UnitTest { + + } + + +} diff --git a/src/main/java/remove_k_digits/RemoveKDigits.java b/src/main/java/remove_k_digits/RemoveKDigits.java new file mode 100644 index 0000000..3b180ff --- /dev/null +++ b/src/main/java/remove_k_digits/RemoveKDigits.java @@ -0,0 +1,32 @@ +package remove_k_digits; + +/** + * Created by lxie on 9/1/18. + */ +public class RemoveKDigits { + + public class Solution { + + public String removeKdigits(String num, int k) { + String res = ""; + int n = num.length(), keep = n - k; + for (char c : num.toCharArray()) { + while (k != 0 && res.length() != 0 && res.charAt(res.length()-1) > c) { + res = res.substring(0, res.length()-1); + --k; // remove at most k numbers + } + res += c; + } + res = res.substring(0, keep); + while (res.length() != 0 && res.charAt(0) == '0') res = res.substring(1); + return res.isEmpty() ? "0" : res; + } + + } + + public class UnitTest { + + } + + +} diff --git a/src/main/java/remove_linked_list_elements/RemoveLinkedListElement.java b/src/main/java/remove_linked_list_elements/RemoveLinkedListElement.java new file mode 100644 index 0000000..79cccb8 --- /dev/null +++ b/src/main/java/remove_linked_list_elements/RemoveLinkedListElement.java @@ -0,0 +1,32 @@ +package remove_linked_list_elements; + +import common.ListNode; + +/** + * Created by lxie on 2/5/18. + */ +public class RemoveLinkedListElement { + + public class Solution { + ListNode removeElements(ListNode head, int val) { + ListNode dummy = new ListNode(-1); + ListNode pre = dummy; + dummy.next = head; + while (pre.next != null) { + if (pre.next.val == val) { + ListNode t = pre.next; + pre.next = t.next; + t.next = null; + } else { + pre = pre.next; + } + } + return dummy.next; + } + } + + public static class UnitTest { + + } + +} diff --git a/src/main/java/reorder_list/ReorderList.java b/src/main/java/reorder_list/ReorderList.java new file mode 100644 index 0000000..49c3e80 --- /dev/null +++ b/src/main/java/reorder_list/ReorderList.java @@ -0,0 +1,60 @@ +package reorder_list; + +import common.ListNode; + +public class ReorderList { + + public class Solution { + private ListNode reverse(ListNode head) { + ListNode pre = null; + ListNode p = head; + while (p != null) { + ListNode temp = p.next; + p.next = pre; + pre = p; + p = temp; + } + return pre; + } + + private ListNode[] split(ListNode head) { + ListNode[] lists = new ListNode[2]; + lists[0] = head; + if (head == null || head.next == null) { + return lists; + } + ListNode slow = head; + ListNode fast = head.next.next; + while (fast != null) { + slow = slow.next; + if (fast.next == null) { + break; + } + fast = fast.next.next; + } + lists[1] = slow.next; + slow.next = null; + return lists; + } + + private void zip(ListNode l1, ListNode l2) { + while (l2 != null) { + ListNode temp = l1.next; + l1.next = l2; + l1 = temp; + temp = l2.next; + l2.next = l1; + l2 = temp; + } + } + + public void reorderList(ListNode head) { + ListNode[] lists = split(head); + lists[1] = reverse(lists[1]); + zip(lists[0], lists[1]); + } + } + + public static class UnitTest { + } +} diff --git a/src/main/java/repeated_dna_sequences/RepeatedDNASequences.java b/src/main/java/repeated_dna_sequences/RepeatedDNASequences.java new file mode 100644 index 0000000..29ca795 --- /dev/null +++ b/src/main/java/repeated_dna_sequences/RepeatedDNASequences.java @@ -0,0 +1,32 @@ +package repeated_dna_sequences; + +import java.util.*; + +public class RepeatedDNASequences { + + public class Solution { + public List findRepeatedDnaSequences1(String s) { + if (s.length() < 10) return new ArrayList<>(); + char[] si = s.toCharArray(); + Set res = new HashSet<>(); + Set st= new HashSet<>(); + Map m = new HashMap<> (); + m.put('A', 0); m.put('C', 1); m.put('G', 2); m.put('T', 3); + int cur = 0, i = 0; + while (i < 9) cur = cur << 2 | m.get(si[i++]); + while (i < s.length()) { + cur = ((cur & 0x3ffff) << 2) | (m.get(si[i++])); // 20 bits for 10-letter-long + if (st.contains(cur)) res.add(s.substring(i - 10, i)); + else st.add(cur); + } + return new ArrayList<>(res); + + } + + } + + public static class UnitTest { + + } +} + diff --git a/src/main/java/repeated_substring_pattern/RepeatedSubstringPattern.java b/src/main/java/repeated_substring_pattern/RepeatedSubstringPattern.java new file mode 100644 index 0000000..8140698 --- /dev/null +++ b/src/main/java/repeated_substring_pattern/RepeatedSubstringPattern.java @@ -0,0 +1,32 @@ +package repeated_substring_pattern; + +/** + * Created by lxie on 9/3/18. + */ +public class RepeatedSubstringPattern { + + public class Solution { + + public boolean repeatedSubstringPattern(String str) { + int n = str.length(); + for (int i = n / 2; i >= 1; --i) { + if (n % i == 0) { + int c = n / i; + String t = ""; + for (int j = 0; j < c; ++j) { + t += str.substring(0, i); + } + if (t.compareTo(str) == 0) return true; + } + } + return false; + } + } + + public class UnitTest { + + + } + + +} diff --git a/src/main/java/replace_words/RepaceWords.java b/src/main/java/replace_words/RepaceWords.java new file mode 100644 index 0000000..3aea96c --- /dev/null +++ b/src/main/java/replace_words/RepaceWords.java @@ -0,0 +1,76 @@ +package replace_words; + +import java.util.List; + +/** + * Created by lxie on 8/18/18. + */ +public class RepaceWords { + + class Solution { + + private class TreeNode{ + private boolean isWord; + private TreeNode[] children; + + public TreeNode() { + isWord = false; + children = new TreeNode[26]; + } + + } + + public String replaceWords(List dict, String sentence) { + TreeNode root = buildTrie(dict); + StringBuilder sb = new StringBuilder(); + int start = 0, end = 0; + while (start < sentence.length()) { + if (sentence.charAt(start) == ' ') { + sb.append(' '); + start++; + } else { + end = start; + while (end < sentence.length() && sentence.charAt(end) != ' ') { + end++; + } + String word = sentence.substring(start, end); + String prefix = findPrefix(root, word); + sb.append(prefix.isEmpty() ? word : prefix); + start = end; + } + } + return sb.toString(); + } + + private TreeNode buildTrie(List dict) { + TreeNode root = new TreeNode(); + for (String word: dict) { + TreeNode node = root; + for (char ch: word.toCharArray()) { + if (node.children[ch - 'a'] == null) + node.children[ch - 'a'] = new TreeNode(); + node = node.children[ch - 'a']; + } + node.isWord = true; + + } + return root; + } + + private String findPrefix(TreeNode root, String word) { + TreeNode node = root; + StringBuilder sb = new StringBuilder(); + for (char ch : word.toCharArray()) { + if (node.isWord || node.children[ch - 'a'] == null) + break; + + sb.append(ch); + node = node.children[ch - 'a']; + } + + return node.isWord ? sb.toString() : ""; + } + } + + +} diff --git a/src/main/java/restore_ip_addresses/RestoreIPAddresses.java b/src/main/java/restore_ip_addresses/RestoreIPAddresses.java new file mode 100644 index 0000000..6c6e8e3 --- /dev/null +++ b/src/main/java/restore_ip_addresses/RestoreIPAddresses.java @@ -0,0 +1,33 @@ +package restore_ip_addresses; + +import java.util.ArrayList; +import java.util.List; + +public class RestoreIPAddresses { + + public class Solution { + + public List restoreIpAddresses(String s) { + List res = new ArrayList<>(); + helper(s, 0, "", res); + return res; + } + + private void helper(String s, int n, String out, List res) { + if (n == 4) { + if (s.isEmpty()) res.add(out); + } else { + for (int k = 1; k < 4; ++k) { + if (s.length() < k) break; + int val = Integer.parseInt(s.substring(0, k)); + if (val > 255 || k != Integer.toString(val).length()) continue; + helper(s.substring(k), n + 1, out + s.substring(0, k) + (n == 3 ? "" : "."), res); + } + } + } + + } + + public static class UnitTest { + } +} diff --git a/src/main/java/reverse_bits/ReverseBits.java b/src/main/java/reverse_bits/ReverseBits.java new file mode 100644 index 0000000..1798c0c --- /dev/null +++ b/src/main/java/reverse_bits/ReverseBits.java @@ -0,0 +1,15 @@ +package reverse_bits; + +public class ReverseBits { + + public class Solution { + public int reverseBits(int n) { + int res = 0; + for (int i = 0; i < 32; ++i) { + res |= ((n >> i) & 1) << (31 - i); + } + return res; + } + } +} + diff --git a/src/main/java/reverse_integer/ReverseInteger.java b/src/main/java/reverse_integer/ReverseInteger.java index 19cd66f..5046295 100644 --- a/src/main/java/reverse_integer/ReverseInteger.java +++ b/src/main/java/reverse_integer/ReverseInteger.java @@ -4,34 +4,14 @@ public class ReverseInteger { public class Solution { public int reverse(int x) { - // Minor revision for this question: if overflow, return - // Integer.MIN_VALUE or Integer.MAX_VALUE - if (x == Integer.MIN_VALUE) { - return x; - } - boolean overflow = false; - boolean negative = x < 0; - x = Math.abs(x); - int y = 0; + long res = 0; while (x != 0) { - if (Integer.MAX_VALUE / 10 < y) { - overflow = true; - break; - } - y *= 10; - int digit = x % 10; + res = 10 * res + x % 10; x /= 10; - if (Integer.MAX_VALUE - digit < y) { - overflow = true; - break; - } - y += digit; - } - if (overflow) { - return negative ? Integer.MIN_VALUE : Integer.MAX_VALUE; } - return negative ? -y : y; + return (res > Integer.MAX_VALUE || res < Integer.MIN_VALUE) ? 0 : (int)res; } + } public static class UnitTest { diff --git a/src/main/java/reverse_linked_list/ReverseLinkedList.java b/src/main/java/reverse_linked_list/ReverseLinkedList.java new file mode 100644 index 0000000..9e9c063 --- /dev/null +++ b/src/main/java/reverse_linked_list/ReverseLinkedList.java @@ -0,0 +1,21 @@ +package reverse_linked_list; + +import common.ListNode; + +public class ReverseLinkedList { + + public class Solution { + public ListNode reverseList(ListNode head) { + ListNode reversed = null; + ListNode p = head; + while (p != null) { + ListNode temp = p.next; + p.next = reversed; + reversed = p; + p = temp; + } + return reversed; + } + } +} + diff --git a/src/main/java/reverse_linked_list_ii/ReverseLinkedListII.java b/src/main/java/reverse_linked_list_ii/ReverseLinkedListII.java new file mode 100644 index 0000000..761a68c --- /dev/null +++ b/src/main/java/reverse_linked_list_ii/ReverseLinkedListII.java @@ -0,0 +1,39 @@ +package reverse_linked_list_ii; + +import common.ListNode; + +public class ReverseLinkedListII { + + public class Solution { + public ListNode reverseBetween(ListNode head, int m, int n) { + ListNode dummy = new ListNode(0); + dummy.next = head; + ListNode prefix = dummy; + int count = n - m + 1; + m--; + while (m > 0) { + prefix = prefix.next; + m--; + } + ListNode pre = null; + ListNode p = prefix.next; + ListNode reversedTail = p; + while (count > 0) { + ListNode temp = p.next; + p.next = pre; + pre = p; + p = temp; + count--; + } + prefix.next = pre; + if (reversedTail != null) { + reversedTail.next = p; + } + return dummy.next; + } + } + + public static class UnitTest { + + } +} diff --git a/src/main/java/reverse_nodes_in_kgroup/ReverseNodesinkGroup.java b/src/main/java/reverse_nodes_in_kgroup/ReverseNodesinkGroup.java new file mode 100644 index 0000000..900e8e6 --- /dev/null +++ b/src/main/java/reverse_nodes_in_kgroup/ReverseNodesinkGroup.java @@ -0,0 +1,50 @@ +package reverse_nodes_in_kgroup; + +import common.ListNode; + +public class ReverseNodesinkGroup { + + public static class Solution { + public ListNode reverseKGroup(ListNode head, int k) { + ListNode cur = head; + for (int i = 0; i < k; ++i) { + if (cur == null) return head; + cur = cur.next; + } + ListNode new_head = reverse(head, cur); + head.next = reverseKGroup(cur, k); + return new_head; + } + + public ListNode reverse(ListNode head, ListNode tail) { + ListNode pre = tail; + while (head != tail) { + ListNode t = head.next; + head.next = pre; + pre = head; + head = t; + } + return pre; + } + } + + public static void main(String[] args) { + Solution test = new Solution(); + ListNode node1 = new ListNode(1); + ListNode node2 = new ListNode(2); + ListNode node3 = new ListNode(3); + ListNode node4 = new ListNode(4); + ListNode node5 = new ListNode(5); + + node1.next = node2; + node2.next = node3; + node3.next = node4; + node4.next = node5; + + ListNode head = test.reverseKGroup(node1, 3); + while (head != null) { + System.out.println(head.val + " "); + head = head.next; + } + } +} diff --git a/src/main/java/reverse_pairs/ReversePairs.java b/src/main/java/reverse_pairs/ReversePairs.java new file mode 100644 index 0000000..21d82b9 --- /dev/null +++ b/src/main/java/reverse_pairs/ReversePairs.java @@ -0,0 +1,34 @@ +package reverse_pairs; + +import java.util.Arrays; + +/** + * Created by lxie on 9/21/18. + */ +public class ReversePairs { + + public class Solution { + + public int reversePairs(int[] nums) { + return mergeSort(nums, 0, nums.length - 1); + } + + private int mergeSort(int[] nums, int left, int right) { + if (left >= right) return 0; + int mid = left + (right - left) / 2; + int res = mergeSort(nums, left, mid) + mergeSort(nums, mid + 1, right); + for (int i = left, j = mid + 1; i <= mid; ++i) { + while (j <= right && nums[i] / 2.0 > nums[j]) ++j; + res += j - (mid + 1); + } + Arrays.sort(nums, left, right + 1); + return res; + } + } + + public class UnitTest { + + + + } +} diff --git a/src/main/java/reverse_words_in_a_string/ReverseWordsinaString.java b/src/main/java/reverse_words_in_a_string/ReverseWordsinaString.java new file mode 100644 index 0000000..bf4855b --- /dev/null +++ b/src/main/java/reverse_words_in_a_string/ReverseWordsinaString.java @@ -0,0 +1,50 @@ +package reverse_words_in_a_string; + +public class ReverseWordsinaString { + + public class Solution { + public String reverseWords(String s) { + String[] tokens = s.split(" +"); + StringBuilder r = new StringBuilder(); + boolean isFirst = true; + for (int i = tokens.length - 1; i >= 0; i--) { + String token = tokens[i]; + if (token.isEmpty()) { + continue; + } + if (isFirst) { + isFirst = false; + } else { + r.append(' '); + } + r.append(token); + } + return r.toString(); + } + + public String reverseWords1(String s0) { + int left = 0; char[] s = s0.toCharArray(); + for (int i = 0; i <= s.length; ++i) { + if (i == s.length || s[i] == ' ') { + reverse(s, left, i - 1); + left = i + 1; + } + } + return new String(reverse(s, 0, s.length - 1)); + } + + public char[] reverse(char[] s, int left, int right) { + while (left < right) { + char t = s[left]; + s[left] = s[right]; + s[right] = t; + ++left; --right; + } + return s; + } + } + + public static class UnitTest { + + } +} diff --git a/src/main/java/roman_to_integer/RomantoInteger.java b/src/main/java/roman_to_integer/RomantoInteger.java index 5906303..be3ab8d 100644 --- a/src/main/java/roman_to_integer/RomantoInteger.java +++ b/src/main/java/roman_to_integer/RomantoInteger.java @@ -6,30 +6,25 @@ public class RomantoInteger { public class Solution { - private Map symbols = new HashMap(); + private Map m = new HashMap(); { - symbols.put('M', 1000); - symbols.put('D', 500); - symbols.put('C', 100); - symbols.put('L', 50); - symbols.put('X', 10); - symbols.put('V', 5); - symbols.put('I', 1); + m.put('M', 1000); + m.put('D', 500); + m.put('C', 100); + m.put('L', 50); + m.put('X', 10); + m.put('V', 5); + m.put('I', 1); } public int romanToInt(String s) { - int num = 0; - num += symbols.get(s.charAt(s.length() - 1)); - for (int i = s.length() - 2; i >= 0; i--) { - char c = s.charAt(i); - char nextC = s.charAt(i + 1); - if (symbols.get(c) < symbols.get(nextC)) { - num -= symbols.get(c); - } else { - num += symbols.get(c); - } + int res = 0; + for (int i = 0; i < s.length(); ++i) { + int val = m.get(s.charAt(i)); + if (i == s.length() - 1 || m.get(s.charAt(i+1)) <= m.get(s.charAt(i))) res += val; + else res -= val; } - return num; + return res; } } diff --git a/src/main/java/rotate_array/RotateArray.java b/src/main/java/rotate_array/RotateArray.java new file mode 100644 index 0000000..d1aad28 --- /dev/null +++ b/src/main/java/rotate_array/RotateArray.java @@ -0,0 +1,24 @@ +package rotate_array; + +public class RotateArray { + + public class Solution { + private void reverse(int[] nums, int begin, int end) { + while (begin < end) { + int temp = nums[begin]; + nums[begin] = nums[end]; + nums[end] = temp; + begin++; + end--; + } + } + + public void rotate(int[] nums, int k) { + k = k % nums.length; + reverse(nums, 0, nums.length - 1); + reverse(nums, 0, k - 1); + reverse(nums, k, nums.length - 1); + } + } +} + diff --git a/src/main/java/rotate_list/RotateList.java b/src/main/java/rotate_list/RotateList.java index 13d433a..095b3c7 100644 --- a/src/main/java/rotate_list/RotateList.java +++ b/src/main/java/rotate_list/RotateList.java @@ -5,43 +5,33 @@ public class RotateList { public class Solution { - public ListNode rotateRight(ListNode head, int n) { - if (head == null) { - return head; + public ListNode rotateRight(ListNode head, int k) { + if (head == null) return null; + int n = 0; + ListNode cur = head; + while (cur != null) { + ++n; + cur = cur.next; } - int k = n; - int listSize = 0; - ListNode end = head; - while (k > 0) { - end = end.next; - k--; - listSize++; - if (end == null) { - k = n % listSize; - end = head; - while (k > 0) { - end = end.next; - k--; - } - break; - } + k %= n; + ListNode fast = head, slow = head; + for (int i = 0; i < k; ++i) { + if (fast != null) fast = fast.next; } - if (head == end) { - return head; + if (fast == null) return head; + while (fast.next != null) { + fast = fast.next; + slow = slow.next; } - ListNode start = head; - while (end.next != null) { - end = end.next; - start = start.next; - } - end.next = head; - head = start.next; - start.next = null; - return head; + fast.next = head; + fast = slow.next; + slow.next = null; + return fast; } - } - public static class UnitTest { + public class UnitTest { + + } } } diff --git a/src/main/java/rotated_digits/RotatedDigits.java b/src/main/java/rotated_digits/RotatedDigits.java new file mode 100644 index 0000000..487e92b --- /dev/null +++ b/src/main/java/rotated_digits/RotatedDigits.java @@ -0,0 +1,35 @@ +package rotated_digits; + +/** + * Created by lxie on 7/10/18. + */ +public class RotatedDigits { + + public class Solution { + + public int rotatedDigits(int N) { + int res = 0; + for (int i = 1; i <= N; ++i) { + if (check(i)) ++res; + } + return res; + } + + private boolean check(int k) { + String str = Integer.toString(k); + boolean flag = false; + for (char c : str.toCharArray()) { + if (c == '3' || c == '4' || c == '7') return false; + if (c == '2' || c == '5' || c == '6' || c == '9') flag = true;; + } + return flag; + } + + } + + public class UnitTest { + + + + } +} diff --git a/src/main/java/russian_doll_envelopes/RussianDollEnvelopes.java b/src/main/java/russian_doll_envelopes/RussianDollEnvelopes.java new file mode 100644 index 0000000..6b6da34 --- /dev/null +++ b/src/main/java/russian_doll_envelopes/RussianDollEnvelopes.java @@ -0,0 +1,43 @@ +package russian_doll_envelopes; + +import java.util.Arrays; +import java.util.Comparator; + +/** + * Created by lxie on 9/10/17. + */ +public class RussianDollEnvelopes { + + public class Solution { + public int maxEnvelopes(int[][] envelopes) { + int res = 0, n = envelopes.length; + int[] dp = new int[n]; + Arrays.fill(dp, 1); + Arrays.sort(envelopes, new Comparator(){ + public int compare(int[] arr1, int[] arr2){ + if(arr1[0] == arr2[0]) + return arr1[1] - arr2[1]; + else + return arr1[0] - arr2[0]; + } + }); + for (int i = 0; i < n; ++i) { + for (int j = 0; j < i; ++j) { + if (envelopes[i][0] > envelopes[j][0] && envelopes[i][1] > envelopes[j][1]) { + dp[i] = Math.max(dp[i], dp[j] + 1); + } + } + res = Math.max(res, dp[i]); + } + return res; + + } + } + + + public static void main(String[] args) { + + } + + +} diff --git a/src/main/java/scramble_string/ScrambleString.java b/src/main/java/scramble_string/ScrambleString.java new file mode 100644 index 0000000..36a0e51 --- /dev/null +++ b/src/main/java/scramble_string/ScrambleString.java @@ -0,0 +1,40 @@ +package scramble_string; + +public class ScrambleString { + + public class Solution { + public boolean isScramble(String s1, String s2) { + if (s1.length() != s2.length()) return false; + if (s1.equals(s2)) { + return true; + } + int len = s1.length(); + boolean[][][] dp = new boolean[len][len][len + 1]; + for (int i = 0; i < len; i++) { + for (int j = 0; j < len; j++) { + dp[i][j][1] = s1.charAt(i) == s2.charAt(j); + } + } + + for (int l = 2; l <= len; l++) { + for (int i = 0; i <= len - l; i++) { + for (int j = 0; j <= len - l; j++) { + for (int p = 1; p < l; p++) { + if ((dp[i][j][p] && dp[i + p][j + p][l - p]) + || (dp[i][j + l - p][p] && dp[i + p][j][l + - p])) { + dp[i][j][l] = true; + break; + } + } + } + } + } + return dp[0][0][len]; + } + } + + public static class UnitTest { + + } +} diff --git a/src/main/java/search_a_2d_matrix_ii/Search2DMatrixII.java b/src/main/java/search_a_2d_matrix_ii/Search2DMatrixII.java new file mode 100644 index 0000000..d63e653 --- /dev/null +++ b/src/main/java/search_a_2d_matrix_ii/Search2DMatrixII.java @@ -0,0 +1,27 @@ +package search_a_2d_matrix_ii; + +/** + * Created by lxie on 3/6/18. + */ +public class Search2DMatrixII { + + public class Solution { + public boolean searchMatrix(int[][] matrix, int target) { + if (matrix.length == 0 || matrix[0].length == 0) return false; + if (target < matrix[0][0] || target > matrix[matrix.length-1][matrix[0].length-1]) + return false; + int x = matrix.length - 1, y = 0; + while (true) { + if (matrix[x][y] > target) --x; + else if (matrix[x][y] < target) ++y; + else return true; + if (x < 0 || y >= matrix[0].length) break; + } + return false; + } + } + + public static class UnitTest { + + } +} diff --git a/src/main/java/search_for_a_range/SearchforaRange.java b/src/main/java/search_for_a_range/SearchforaRange.java index 66efd7f..e3df0f4 100644 --- a/src/main/java/search_for_a_range/SearchforaRange.java +++ b/src/main/java/search_for_a_range/SearchforaRange.java @@ -4,29 +4,25 @@ public class SearchforaRange { public class Solution { - private int lowerBound(int[] A, int left, int right, int target) { - while (left <= right) { + public int[] searchRange(int[] nums, int target) { + int[] res = new int[] {-1, -1}; + if (nums.length == 0) return res; + int left = 0, right = nums.length - 1; + while (left < right) { int mid = left + (right - left) / 2; - if (A[mid] < target) { - left = mid + 1; - } else { - right = mid - 1; - } + if (nums[mid] < target) left = mid + 1; + else right = mid; } - return left; - } - - public int[] searchRange(int[] A, int target) { - int[] ans = new int[2]; - int begin = lowerBound(A, 0, A.length - 1, target); - if (begin < A.length && A[begin] == target) { - ans[0] = begin; - ans[1] = lowerBound(A, begin + 1, A.length - 1, target + 1) - 1; - } else { - ans[0] = -1; - ans[1] = -1; + if (nums[right] != target) return res; + res[0] = right; + right = nums.length; // edge case - left=0, right=0 + while (left < right) { + int mid = left + (right - left) / 2; + if (nums[mid] <= target) left = mid + 1; + else right= mid; } - return ans; + res[1] = left - 1; + return res; } } diff --git a/src/main/java/search_insert_position/SearchInsertPosition.java b/src/main/java/search_insert_position/SearchInsertPosition.java index 459f686..28f6513 100644 --- a/src/main/java/search_insert_position/SearchInsertPosition.java +++ b/src/main/java/search_insert_position/SearchInsertPosition.java @@ -6,15 +6,15 @@ public class Solution { public int searchInsert(int[] A, int target) { int left = 0; int right = A.length - 1; - while (left <= right) { + while (left < right) { int mid = left + (right - left) / 2; if (A[mid] < target) { left = mid + 1; } else { - right = mid - 1; + right = mid; } } - return left; + return right; } } diff --git a/src/main/java/sentence_screen_fitting/SentenceScreenFitting.java b/src/main/java/sentence_screen_fitting/SentenceScreenFitting.java new file mode 100644 index 0000000..b855c27 --- /dev/null +++ b/src/main/java/sentence_screen_fitting/SentenceScreenFitting.java @@ -0,0 +1,34 @@ +package sentence_screen_fitting; + +import java.util.List; + +/** + * Created by lxie on 8/19/18. + */ +public class SentenceScreenFitting { + + public class Solution { + + public int wordsTyping(List sentence, int rows, int cols) { + String all = ""; + for (String word : sentence) all += (word + " "); + int start = 0, len = all.length(); + for (int i = 0; i < rows; ++i) { + start += cols; + if (all.charAt(start % len) == ' ') { + ++start; + } else { + while (start > 0 && all.charAt(start - 1) % len != ' ') { + --start; + } + } + } + return start / len; + } + } + + public class UnitTest { + + + } +} diff --git a/src/main/java/sentence_similarity/SentenceSimilarity.java b/src/main/java/sentence_similarity/SentenceSimilarity.java new file mode 100644 index 0000000..d0c7aab --- /dev/null +++ b/src/main/java/sentence_similarity/SentenceSimilarity.java @@ -0,0 +1,45 @@ +package sentence_similarity; + +import common.Pair; + +import java.util.*; + +/** + * Created by lxie on 7/17/18. + */ +public class SentenceSimilarity { + + public boolean areSentencesSimilar(String[] words1, String[] words2, List> pairs) { + if (words1.length != words2.length) return false; + Map> m = new HashMap<>(); + + for (Map.Entry pair : pairs) { + //m[pair.first].insert(pair.second); + if (!m.containsKey(pair.getKey())) { + m.put(pair.getKey(), new HashSet<>(Arrays.asList(pair.getValue()))); + } else { + m.get(pair.getKey()).add(pair.getValue()); + } + } + for (int i = 0; i < words1.length; ++i) { + if (words1[i] == words2[i]) continue; + if((m.containsKey(words1[i]) && m.get(words1[i]).contains(words2[i])) || + (m.containsKey(words2[i]) && m.get(words2[i]).contains(words1[i]))) continue; + return false; + } + return true; + } + + public static void main(String[] args) { + SentenceSimilarity ss = new SentenceSimilarity(); + String[] words1 = {"great", "acting", "skills"}; + String[] words2 = {"fine", "drama", "talent"}; + List> pairs = new ArrayList<>(); + pairs.add(Pair.of("great", "fine")); + pairs.add(Pair.of("acting", "drama")); + pairs.add(Pair.of("skills", "talent")); + + System.out.println(ss.areSentencesSimilar(words1, words2, pairs)); + + } +} diff --git a/src/main/java/sequence_reconstruction/SequenceReconstruction.java b/src/main/java/sequence_reconstruction/SequenceReconstruction.java new file mode 100644 index 0000000..f645c32 --- /dev/null +++ b/src/main/java/sequence_reconstruction/SequenceReconstruction.java @@ -0,0 +1,38 @@ +package sequence_reconstruction; + +import java.util.HashMap; +import java.util.Map; + +/** + * Created by lxie on 8/31/18. + */ +public class SequenceReconstruction { + + public class Solution { + public boolean sequenceReconstruction(int[] org, int[][] seqs) { + Map m = new HashMap<>(); + Map pre = new HashMap<>(); + for (int i = 0; i < org.length; ++i) m.put(org[i], i); + for (int[] seq : seqs) { + for (int i = 0; i < seq.length; ++i) { + if (!m.containsKey(seq[i])) return false; + if (i > 0 && m.get(seq[i - 1]) >= m.get(seq[i])) return false; + if (!pre.containsKey(seq[i])) { + pre.put(seq[i], (i > 0) ? m.get(seq[i - 1]) : -1); + } else { + pre.put(seq[i], Math.max(pre.get(seq[i]), (i > 0) ? m.get(seq[i - 1]) : -1)); + } + } + } + for (int i = 0; i < org.length; ++i) { + if (pre.get(org[i]) != i - 1) return false; + } + return true; + } + } + + public class UnitTest { + + } + +} diff --git a/src/main/java/serialize_deserialize_binary_tree/SerializeDeserializeBTree.java b/src/main/java/serialize_deserialize_binary_tree/SerializeDeserializeBTree.java new file mode 100644 index 0000000..2faf68f --- /dev/null +++ b/src/main/java/serialize_deserialize_binary_tree/SerializeDeserializeBTree.java @@ -0,0 +1,99 @@ +package serialize_deserialize_binary_tree; + +import common.TreeNode; + +import java.util.LinkedList; + +/** + * Created by lxie on 12/7/17. + */ +public class SerializeDeserializeBTree { + + public static class Solution { + public static class Codec { + + public static String serialize(TreeNode root) { + if(root==null){ + return ""; + } + + StringBuilder sb = new StringBuilder(); + + LinkedList queue = new LinkedList(); + + queue.add(root); + while(!queue.isEmpty()){ + TreeNode t = queue.poll(); + if(t!=null){ + sb.append(String.valueOf(t.val) + ","); + queue.add(t.left); + queue.add(t.right); + }else{ + sb.append("#,"); + } + } + + sb.deleteCharAt(sb.length()-1); + System.out.println(sb.toString()); + return sb.toString(); + } + + // Decodes your encoded data to tree. + public static TreeNode deserialize(String data) { + if(data==null || data.length()==0) + return null; + + String[] arr = data.split(","); + TreeNode root = new TreeNode(Integer.parseInt(arr[0])); + + + LinkedList queue = new LinkedList(); + queue.add(root); + + int i=1; + while(!queue.isEmpty()){ + TreeNode t = queue.poll(); + + if(t==null) + continue; + + if(!arr[i].equals("#")){ + t.left = new TreeNode(Integer.parseInt(arr[i])); + queue.offer(t.left); + + }else{ + t.left = null; + queue.offer(null); + } + i++; + + if(!arr[i].equals("#")){ + t.right = new TreeNode(Integer.parseInt(arr[i])); + queue.offer(t.right); + + }else{ + t.right = null; + queue.offer(null); + } + i++; + } + + return root; + } + + + } + + } + + public static void main(String[] args) { + TreeNode root = new TreeNode(1); + TreeNode left = new TreeNode(2); + TreeNode right = new TreeNode(3); + root.left = left; + root.right = right; + + System.out.println("result1 = " + Solution.Codec.serialize(root)); + System.out.println("result2 = " + Solution.Codec.deserialize("1,2,3,#,#,#,#")); + } +} diff --git a/src/main/java/shopping_offers/ShoppingOffers.java b/src/main/java/shopping_offers/ShoppingOffers.java new file mode 100644 index 0000000..5f4520d --- /dev/null +++ b/src/main/java/shopping_offers/ShoppingOffers.java @@ -0,0 +1,38 @@ +package shopping_offers; + +import java.util.List; + +/** + * Created by lxie on 9/9/18. + */ +public class ShoppingOffers { + + public class Solution { + + public int shoppingOffers(List price, List> special, List needs) { + int res = 0, n = price.size(); + for (int i = 0; i < n; ++i) { + res += price.get(i) * needs.get(i); + } + for (List offer : special) { + boolean isValid = true; + for (int j = 0; j < n; ++j) { + if (needs.get(j) - offer.get(j) < 0) isValid = false; + needs.set(j, needs.get(j) - offer.get(j)); + } + if (isValid) { + res = Math.min(res, shoppingOffers(price, special, needs) + offer.get(offer.size()-1)); + } + for (int j = 0; j < n; ++j) { + needs.set(j, needs.get(j) + offer.get(j)); // backtracking + } + } + return res; + } + } + + public class UnitTest { + + } + +} diff --git a/src/main/java/shortest_distance_from_all_buildings/ShortestDistanceToBuildings.java b/src/main/java/shortest_distance_from_all_buildings/ShortestDistanceToBuildings.java new file mode 100644 index 0000000..a8abcf7 --- /dev/null +++ b/src/main/java/shortest_distance_from_all_buildings/ShortestDistanceToBuildings.java @@ -0,0 +1,50 @@ +package shortest_distance_from_all_buildings; + +import java.util.LinkedList; +import java.util.Queue; + +/** + * Created by lxie on 1/30/18. + */ +public class ShortestDistanceToBuildings { + + public class Solution { + + public int shortestDistance(int[][] grid) { + int res = Integer.MAX_VALUE, val = 0, m = grid.length, n = grid[0].length; + int[][] sum = grid; + int[][] dirs = {{0,-1},{-1,0},{0,1},{1,0}}; + for (int i = 0; i < grid.length; ++i) { + for (int j = 0; j < grid[i].length; ++j) { + if (grid[i][j] == 1) { + res = Integer.MAX_VALUE; + int[][] dist = grid; + Queue q = new LinkedList<>(); + q.add(new int[]{i, j}); + while (!q.isEmpty()) { + int a = q.peek()[0], b = q.peek()[1]; q.poll(); + for (int k = 0; k < dirs.length; ++k) { + int x = a + dirs[k][0], y = b + dirs[k][1]; + if (x >= 0 && x < m && y >= 0 && y < n && grid[x][y] == val) { + --grid[x][y]; + dist[x][y] = dist[a][b] + 1; + sum[x][y] += dist[x][y] - 1; + q.add(new int[]{x, y}); + res = Integer.min(res, sum[x][y]); + } + } + } + --val; // empty land changes in each BFS + } + } + } + return res == Integer.MAX_VALUE ? -1 : res; + } + } + + + public static class UnitTest { + + } + +} diff --git a/src/main/java/shortest_palindrome/ShortestPalindrome.java b/src/main/java/shortest_palindrome/ShortestPalindrome.java new file mode 100644 index 0000000..6c237a1 --- /dev/null +++ b/src/main/java/shortest_palindrome/ShortestPalindrome.java @@ -0,0 +1,26 @@ +package shortest_palindrome; + +/** + * Created by lxie on 12/15/17. + */ +public class ShortestPalindrome { + public class Solution { + public String shortestPalindrome(String s) { + String r = s; + r = new StringBuilder(r).reverse().toString(); + char[] t = (s + "#" + r).toCharArray(); + int[] p = new int[t.length]; + for (int i = 1; i < t.length; ++i) { + int j = p[i - 1]; + while (j > 0 && t[i] != t[j]) j = p[j - 1]; + p[i] = (j += (t[i] == t[j] ? 1 : 0)); + } + return r.substring(0, s.length() - p[t.length - 1]) + s; + } + + } + + public static class UnitTest { + + } +} diff --git a/src/main/java/shortest_unsorted_continuous_subarray/ShortestUnsortedContinuousSubarray.java b/src/main/java/shortest_unsorted_continuous_subarray/ShortestUnsortedContinuousSubarray.java new file mode 100644 index 0000000..4a407a6 --- /dev/null +++ b/src/main/java/shortest_unsorted_continuous_subarray/ShortestUnsortedContinuousSubarray.java @@ -0,0 +1,27 @@ +package shortest_unsorted_continuous_subarray; + +/** + * Created by lxie on 9/13/18. + */ +public class ShortestUnsortedContinuousSubarray { + + public class Solution { + + public int findUnsortedSubarray(int[] nums) { + int n = nums.length, start = -1, end = -2; + int mn = nums[n - 1], mx = nums[0]; + for (int i = 1; i < n; ++i) { + mx = Math.max(mx, nums[i]); + mn = Math.min(mn, nums[n - 1 - i]); + if (mx > nums[i]) end = i; + if (mn < nums[n - 1 - i]) start = n - 1 - i; + } + return end - start + 1; + } + } + + public class UnitTest { + + } + +} diff --git a/src/main/java/shortest_word_distance/ShortestWordDistance.java b/src/main/java/shortest_word_distance/ShortestWordDistance.java new file mode 100644 index 0000000..1a88265 --- /dev/null +++ b/src/main/java/shortest_word_distance/ShortestWordDistance.java @@ -0,0 +1,28 @@ +package shortest_word_distance; + +import java.util.List; + +import static java.lang.StrictMath.abs; + +/** + * Created by lxie on 3/7/18. + */ +public class ShortestWordDistance { + + public class Solution { + int shortestDistance(List words, String word1, String word2) { + int p1 = -1, p2 = -1, res = Integer.MAX_VALUE; + for (int i = 0; i < words.size(); ++i) { + if (words.toArray()[i] == word1) p1 = i; + if (words.toArray()[i] == word2) p2 = i; + if (p1 != -1 && p2 != -1) res = Math.min(res, abs(p1 - p2)); + } + return res; + } + } + + public static class UnitTest { + + } + +} diff --git a/src/main/java/shortest_word_distance_ii/ShortestWordDistanceII.java b/src/main/java/shortest_word_distance_ii/ShortestWordDistanceII.java new file mode 100644 index 0000000..c11a169 --- /dev/null +++ b/src/main/java/shortest_word_distance_ii/ShortestWordDistanceII.java @@ -0,0 +1,37 @@ +package shortest_word_distance_ii; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Created by lxie on 3/7/18. + */ +public class ShortestWordDistanceII { + + private Map> m = new HashMap<>(); + + public ShortestWordDistanceII(List words) { + for (int i = 0; i < words.size(); ++i) { + String s = words.get(i); + if (m.containsKey(s)) m.get(s).add(i); + else + m.put(s, new ArrayList(i)); + } + } + + public int shortest(String word1, String word2) { + int i = 0, j = 0, res = Integer.MAX_VALUE; + int len1 = m.containsKey(word1) ? m.get(word1).size() : -1; + int len2 = m.containsKey(word2) ? m.get(word2).size() : -1; + if (len1 <= 0 || len2 <= 0) return -1; + + while (i < len1 && j < len2) { + res = Math.min(res, Math.abs(m.get(word1).get(i) - m.get(word2).get(j))); + if (m.get(word1).get(i) < m.get(word2).get(j)) ++i; + else ++j; + } + return res; + } +} diff --git a/src/main/java/shortest_word_distance_iii/ShortestWordDistanceIII.java b/src/main/java/shortest_word_distance_iii/ShortestWordDistanceIII.java new file mode 100644 index 0000000..d916220 --- /dev/null +++ b/src/main/java/shortest_word_distance_iii/ShortestWordDistanceIII.java @@ -0,0 +1,28 @@ +package shortest_word_distance_iii; + +import java.util.List; + +import static java.lang.StrictMath.abs; + +/** + * Created by lxie on 3/8/18. + */ +public class ShortestWordDistanceIII { + + public class Solution { + int shortestDistance(List words, String word1, String word2) { + int p1 = words.size(), p2 = -words.size(), res = Integer.MAX_VALUE; + for (int i = 0; i < words.size(); ++i) { + if (words.toArray()[i] == word1) p1 = word1 == word2 ? p2 : i; + if (words.toArray()[i] == word2) p2 = i; + if (p1 != -1 && p2 != -1) res = Math.min(res, abs(p1 - p2)); + } + return res; + } + } + + public static class UnitTest { + + } + +} diff --git a/src/main/java/simplify_path/SimplifyPath.java b/src/main/java/simplify_path/SimplifyPath.java new file mode 100644 index 0000000..886c522 --- /dev/null +++ b/src/main/java/simplify_path/SimplifyPath.java @@ -0,0 +1,36 @@ +package simplify_path; + +import java.util.ArrayDeque; + +public class SimplifyPath { + + public class Solution { + public String simplifyPath(String path) { + String[] splits = path.split("/"); + ArrayDeque stack = new ArrayDeque(); + for (String s : splits) { + if (!s.isEmpty()) { + if (s.equals("..")) { + if (!stack.isEmpty()) { + stack.removeLast(); + } + } else if (s.equals(".")) { + continue; + } else { + stack.offerLast(s); + } + } + } + StringBuilder newPath = new StringBuilder(); + for (String s : stack) { + newPath.append('/'); + newPath.append(s); + } + return newPath.length() == 0 ? "/" : newPath.toString(); + } + } + + public static class UnitTest { + + } +} diff --git a/src/main/java/single_number_ii/SingleNumberII.java b/src/main/java/single_number_ii/SingleNumberII.java index 99e6a2b..0d16ece 100644 --- a/src/main/java/single_number_ii/SingleNumberII.java +++ b/src/main/java/single_number_ii/SingleNumberII.java @@ -3,22 +3,16 @@ public class SingleNumberII { public class Solution { - public int singleNumber(int[] A) { - int[] bits = new int[32]; - for (int a : A) { - for (int i = 0; i < 32; i++) { - if ((a & (1 << i)) != 0) { - bits[i]++; - } - } + public int singleNumber(int[] nums) { + int one = 0, two = 0, three = 0; + for (int i = 0; i < nums.length; ++i) { + two |= one & nums[i]; + one ^= nums[i]; + three = one & two; + one &= ~three; + two &= ~three; } - int ans = 0; - for (int i = 0; i < 32; i++) { - if (bits[i] % 3 == 1) { - ans |= (1 << i); - } - } - return ans; + return one; } } diff --git a/src/main/java/single_number_iii/SingleNumberIII.java b/src/main/java/single_number_iii/SingleNumberIII.java new file mode 100644 index 0000000..21740fd --- /dev/null +++ b/src/main/java/single_number_iii/SingleNumberIII.java @@ -0,0 +1,39 @@ +package single_number_iii; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by lxie on 6/4/18. + */ +public class SingleNumberIII { + + public class Solution { + public List singleNumberIII(int[] A) { + int xor = 0; + for (int i = 0; i < A.length; i++) { + xor ^= A[i]; + } + + int lastBit = xor - (xor & (xor - 1)); + int group0 = 0, group1 = 0; + for (int i = 0; i < A.length; i++) { + if ((lastBit & A[i]) == 0) { + group0 ^= A[i]; + } else { + group1 ^= A[i]; + } + } + + List result = new ArrayList(); + result.add(group0); + result.add(group1); + return result; + } + } + + public class UnitTest { + + } + +} diff --git a/src/main/java/skyline_problem/SkylineProblem.java b/src/main/java/skyline_problem/SkylineProblem.java new file mode 100644 index 0000000..5b1ba83 --- /dev/null +++ b/src/main/java/skyline_problem/SkylineProblem.java @@ -0,0 +1,61 @@ +package skyline_problem; + +import com.google.common.collect.TreeMultiset; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +/** + * Created by lxie on 1/2/18. + */ +public class SkylineProblem { + + public static class Solution { + public List getSkyline(int[][] buildings) { + List h = new ArrayList<>(); + List res = new ArrayList<>(); + TreeMultiset m = TreeMultiset.create(); // sort elements + int pre = 0, cur = 0; + for (int[] a : buildings) { + h.add(new int[] {a[0], -a[2]}); + h.add(new int[] {a[1], a[2]}); + } + + Collections.sort(h, new Comparator() { + public int compare(int[] arr1, int[] arr2) { + if (arr1[0] == arr2[0]) + return arr1[1] - arr2[1]; + else + return arr1[0] - arr2[0]; + } + }); + + m.add(0); + for (int[] a : h) { + if (a[1] < 0) m.add(-a[1]); + else m.remove(a[1]); + cur = m.lastEntry().getElement(); + if (cur != pre) { + res.add(new int[] {a[0], cur} ); + pre = cur; + } + } + return res; + } + + } + + + public static void main(String[] args) { + System.out.println("this is for test"); + Solution sol = new Solution(); + int[][] buildings = {{2, 9, 10}, {3, 7, 15}, {5, 12, 12}, {15, 20, 10}, {19, 24, 8}}; + List result = sol.getSkyline(buildings); + for (int[] a : result) { + System.out.println("[" + a[0] + ", " + a[1] + "], "); + } + + } +} \ No newline at end of file diff --git a/src/main/java/sliding_window_maximum/SlidingWindowMax.java b/src/main/java/sliding_window_maximum/SlidingWindowMax.java new file mode 100644 index 0000000..1f56ad0 --- /dev/null +++ b/src/main/java/sliding_window_maximum/SlidingWindowMax.java @@ -0,0 +1,31 @@ +package sliding_window_maximum; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; + +/** + * Created by lxie on 12/3/17. + */ +public class SlidingWindowMax { + + public static class Solution { + public int[] maxSlidingWindow(int[] nums, int k) { + List res = new ArrayList<>(); + LinkedList q = new LinkedList<>(); // idx + for (int i = 0; i < nums.length; ++i) { + // remove when nums[i-k] is maximum, otherwise already removed + if (!q.isEmpty() && q.getFirst() == i - k) q.removeFirst(); + while (!q.isEmpty() && nums[q.getLast()] < nums[i]) q.removeLast(); + q.add(i); + if (i >= k - 1) res.add(nums[q.getFirst()]); + } + return res.stream().mapToInt(i->i).toArray(); + } + } + + public static class UnitTest { + + } + +} diff --git a/src/main/java/sliding_window_median/SlidingWindowMedian.java b/src/main/java/sliding_window_median/SlidingWindowMedian.java new file mode 100644 index 0000000..15b43e5 --- /dev/null +++ b/src/main/java/sliding_window_median/SlidingWindowMedian.java @@ -0,0 +1,72 @@ +package sliding_window_median; + +import com.google.common.primitives.Doubles; + +import java.util.*; + +/** + * Created by lxie on 9/10/18. + */ +public class SlidingWindowMedian { + + public double[] medianSlidingWindow(int[] nums, int k) { + List res = new ArrayList<>(); + if (nums == null || nums.length == 0) { + return Doubles.toArray(res); + } + PriorityQueue minHeap = new PriorityQueue<>(); + PriorityQueue maxHeap = new PriorityQueue<>(new Comparator() { + public int compare(Integer x, Integer y) { + return y - x; + } + }); + + double curMedian; + if (k > 1) { + maxHeap.add(nums[0]); + for (int i = 1; i < k - 1; i++) { + int x = maxHeap.peek(); + if (nums[i] <= x) { + maxHeap.add(nums[i]); + } else { + minHeap.add(nums[i]); + } + } + curMedian = maxHeap.peek(); + } else { + curMedian = 0; + } + + for (int i = k - 1; i < nums.length; i++) { + if (nums[i] <= curMedian) { + maxHeap.add(nums[i]); + } else { + minHeap.add(nums[i]); + } + while (maxHeap.size() > minHeap.size()+1) { + minHeap.add(maxHeap.poll()); + } + while (maxHeap.size() < minHeap.size()) { + maxHeap.add(minHeap.poll()); + } + curMedian = maxHeap.peek(); + res.add(curMedian); + if (nums[i - k + 1] <= curMedian) { + maxHeap.remove(nums[i - k + 1]); + } else { + minHeap.remove(nums[i - k + 1]); + } + } + + return Doubles.toArray(res); + } + + public static void main(String[] args) { + SlidingWindowMedian s = new SlidingWindowMedian(); + int[] a = {1,3,-1,-3,5,3,6,7}; + double[] res = s.medianSlidingWindow(a, 3); + System.out.println("result is " + Arrays.toString(res)); + + } + +} diff --git a/src/main/java/smaller_numbers_after_self/SmallerAfterSelf.java b/src/main/java/smaller_numbers_after_self/SmallerAfterSelf.java new file mode 100644 index 0000000..143c9cf --- /dev/null +++ b/src/main/java/smaller_numbers_after_self/SmallerAfterSelf.java @@ -0,0 +1,35 @@ +package smaller_numbers_after_self; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * Created by lxie on 7/2/18. + */ +public class SmallerAfterSelf { + + public class Solution { + + public List countSmaller(int[] nums) { + List t = new ArrayList<>(); + Integer[] res = new Integer[nums.length]; + for (int i = nums.length - 1; i >= 0; --i) { + int left = 0, right = t.size(); + while (left < right) { + int mid = left + (right - left) / 2; + if (t.get(mid) >= nums[i]) right = mid; + else left = mid + 1; + } + res[i] = right; // for each i get count + t.add(right, nums[i]); + } + return Arrays.asList(res); + } + } + + public class UnitTest4 { + + } + +} diff --git a/src/main/java/smallest_good_base/SmallestGoodBase.java b/src/main/java/smallest_good_base/SmallestGoodBase.java new file mode 100644 index 0000000..3b7e532 --- /dev/null +++ b/src/main/java/smallest_good_base/SmallestGoodBase.java @@ -0,0 +1,33 @@ +package smallest_good_base; + +/** + * Created by lxie on 9/10/18. + */ +public class SmallestGoodBase { + + public class Solution { + + public String smallestGoodBase(String n) { + long num = Long.parseLong(n); + for (int i = (int) (Math.log(num + 1) / Math.log(2)); i >= 2; --i) { // smallest base first: 2^m <= n + long left = 2, right = (long) Math.pow(num, 1.0 / (i - 1)) + 1; + while (left < right) { + long mid = left + (right - left) / 2, sum = 0; + for (int j = 0; j < i; ++j) { + sum = sum * mid + 1; + } + if (sum == num) return Long.toString(mid); + else if (sum < num) left = mid + 1; + else right = mid; + } + } + return Long.toString(num - 1); + } + } + + public class UnitTest { + + + } + +} diff --git a/src/main/java/smallest_rectangle_enclosing_black_pixels/MinArea.java b/src/main/java/smallest_rectangle_enclosing_black_pixels/MinArea.java new file mode 100644 index 0000000..4552ad4 --- /dev/null +++ b/src/main/java/smallest_rectangle_enclosing_black_pixels/MinArea.java @@ -0,0 +1,41 @@ +package smallest_rectangle_enclosing_black_pixels; + +/** + * Created by lxie on 6/26/18. + */ +public class MinArea { + + public class Solution { + + public int minArea(char[][] image, int x, int y) { + int[] left = {y}; int[] right = {y}; + int[] up = {x}; int[] down = {x}; + dfs(image, x, y, left, right, up, down); + return (right[0] - left[0] + 1) * (down[0] - up[0] + 1); + } + + private void dfs(char[][] image, int x, int y, int[] left, + int[] right, int[] up, int[] down) { + if (x < 0 || x >= image.length || y < 0 || y >= image[0].length || + image[x][y] != '1') return; + left[0] = Math.min(left[0], y); + right[0] = Math.max(right[0], y); + up[0] = Math.min(up[0], x); + down[0] = Math.max(down[0], x); + image[x][y] = '2'; + dfs(image, x + 1, y, left, right, up, down); + dfs(image, x - 1, y, left, right, up, down); + dfs(image, x, y + 1, left, right, up, down); + dfs(image, x, y - 1, left, right, up, down); + } + + + } + + public class UnitTest { + + + } + + +} diff --git a/src/main/java/snake_game/DesignSnakeGame.java b/src/main/java/snake_game/DesignSnakeGame.java new file mode 100644 index 0000000..758ac30 --- /dev/null +++ b/src/main/java/snake_game/DesignSnakeGame.java @@ -0,0 +1,64 @@ +package snake_game; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by lxie on 1/25/18. + */ +public class DesignSnakeGame { + + public class Solution { + + public class SnakeGame { + + private int width, height, score; + private List food = new ArrayList<>(); + private List pos = new ArrayList<>(); + + public void SnakeGame(int width, int height, List food) { + this.width = width; + this.height = height; + this.food = food; + score = 0; + pos.add(new int[] {0, 0}); + } + + public int move(String direction) { + int[] head = pos.get(0), tail = pos.get(pos.size()-1); + pos.remove(pos.size()-1); + if (direction == "U") --head[0]; + else if (direction == "L") --head[1]; + else if (direction == "R") ++head[1]; + else if (direction == "D") ++head[0]; + if (count(pos, head) > 0 || head[0] < 0 || head[0] >= height || head[1] < 0 || head[1] >= width) { + return -1; + } + pos.add(0, head); + if (food.size() != 0 && head == food.get(0)) { + food.remove(0); + pos.add(tail); + ++score; + } + return score; + } + + private int count(List pos, int[] head) { + int count = 0; + for (int[] a : pos) { + if (a == head) count++; + } + return count; + } + + } + + } + + public static class UnitTest { + + + } + + +} diff --git a/src/main/java/sort_chars_by_frequency/SortCharsByFrequency.java b/src/main/java/sort_chars_by_frequency/SortCharsByFrequency.java new file mode 100644 index 0000000..05e44b1 --- /dev/null +++ b/src/main/java/sort_chars_by_frequency/SortCharsByFrequency.java @@ -0,0 +1,50 @@ +package sort_chars_by_frequency; + +import common.Pair; + +import java.util.*; + +/** + * Created by lxie on 7/25/18. + */ + +/* time limit exceeds */ +public class SortCharsByFrequency { + + public String frequencySort(String s) { + String res = ""; + PriorityQueue> q = new PriorityQueue<>(100, + new Comparator>() { + @Override + public int compare(Map.Entry o1, Map.Entry o2) { + return o2.getKey() - o1.getKey(); + } + }); + + Map m = new HashMap<>(); + for (char c : s.toCharArray()) { + if (m.containsKey(c)) + m.put(c, m.get(c) + 1); + else + m.put(c, 1); + } + for (Map.Entry a : m.entrySet()) + q.add(Pair.of(a.getValue(), a.getKey())); + while (!q.isEmpty()) { + Map.Entry t = q.peek(); q.poll(); + for (int i=0; i= 0 ? n - 1 : 0; + while (i <= j) { + if (a >= 0) { + res[idx--] = cal(nums[i], a, b, c) >= cal(nums[j], a, b, c) ? cal(nums[i++], a, b, c) : cal(nums[j--], a, b, c); + } else { + res[idx++] = cal(nums[i], a, b, c) >= cal(nums[j], a, b, c) ? cal(nums[j--], a, b, c) : cal(nums[i++], a, b, c); + } + } + return res; + } + int cal(int x, int a, int b, int c) { + return a * x * x + b * x + c; + } + + } + + public class UnitTest { + + } + + +} diff --git a/src/main/java/sparse_matrix_multiplication/SparseMatrixMultiplication.java b/src/main/java/sparse_matrix_multiplication/SparseMatrixMultiplication.java new file mode 100644 index 0000000..5f75a9f --- /dev/null +++ b/src/main/java/sparse_matrix_multiplication/SparseMatrixMultiplication.java @@ -0,0 +1,49 @@ +package sparse_matrix_multiplication; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by lxie on 1/21/18. + */ +public class SparseMatrixMultiplication { + + public class Solution { + + public int[][] multiply(int[][] A, int[][] B) { + // Write your code here + int n = A.length; + int m = B[0].length; + int t = A[0].length; + int[][] C = new int[n][m]; + + List> col = new ArrayList<>(); + for (int i = 0; i < t; i++) { + col.add(new ArrayList<>()); + for (int j = 0; j < m; j++) { + if (B[i][j] != 0) { + col.get(i).add(j); + } + } + } + for (int i = 0; i < n; i++) { + for (int k = 0; k < t; k++) { + if (A[i][k] == 0) { + continue; + } + for (int p = 0; p < col.get(k).size(); p++) { + int j = col.get(k).get(p); + C[i][j] += A[i][k] * B[k][j]; + } + } + } + return C; + } + + } + + public static class UnitTest { + + } + +} diff --git a/src/main/java/spiral_matrix_ii/SpiralMatrixII.java b/src/main/java/spiral_matrix_ii/SpiralMatrixII.java new file mode 100644 index 0000000..71e422d --- /dev/null +++ b/src/main/java/spiral_matrix_ii/SpiralMatrixII.java @@ -0,0 +1,36 @@ +package spiral_matrix_ii; + +public class SpiralMatrixII { + + public class Solution { + public int[][] generateMatrix(int n) { + int[][] matrix = new int[n][n]; + int num = 0; + int begin = 0; + int end = n - 1; + while (begin <= end) { + for (int i = begin; i <= end; i++) { + matrix[begin][i] = ++num; + } + for (int i = begin + 1; i < end; i++) { + matrix[i][end] = ++num; + } + if (begin != end) { + for (int i = end; i >= begin; i--) { + matrix[end][i] = ++num; + } + for (int i = end - 1; i > begin; i--) { + matrix[i][begin] = ++num; + } + } + begin++; + end--; + } + return matrix; + } + } + + public static class UnitTest { + + } +} diff --git a/src/main/java/split_array_into_consecutive_subsequences/SplitArray2ConseqSubseq.java b/src/main/java/split_array_into_consecutive_subsequences/SplitArray2ConseqSubseq.java new file mode 100644 index 0000000..2d55754 --- /dev/null +++ b/src/main/java/split_array_into_consecutive_subsequences/SplitArray2ConseqSubseq.java @@ -0,0 +1,51 @@ +package split_array_into_consecutive_subsequences; + +import java.util.HashMap; +import java.util.Map; + +/** + * Created by lxie on 9/18/18. + */ +public class SplitArray2ConseqSubseq { + + public boolean isPossible(int[] nums) { + Map freq = new HashMap<>(); + Map need = new HashMap<>(); + for (int num : nums) { + if (freq.containsKey(num)) freq.put(num, freq.get(num) + 1); + else + freq.put(num, 1); + } + for (int num : nums) { + if (freq.containsKey(num) && freq.get(num) == 0) continue; + else if (need.containsKey(num) && need.get(num) > 0) { + need.put(num, need.get(num) - 1); + if (need.containsKey(num+1)) + need.put(num+1, need.get(num+1) + 1); + else + need.put(num+1, 1); + } else if (freq.containsKey(num+1) && freq.get(num + 1) > 0 && + freq.containsKey(num+2) && freq.get(num + 2) > 0) { + freq.put(num+1, freq.get(num + 1) - 1); + freq.put(num+2, freq.get(num + 2) - 1); + if (need.containsKey(num+3)) + need.put(num+3, need.get(num+3) + 1); + else + need.put(num+3, 1); + } else return false; + freq.put(num, freq.get(num) - 1); + } + return true; + } + + public static void main(String[] args) { + SplitArray2ConseqSubseq s = new SplitArray2ConseqSubseq(); + int[] input = {1,2,3,3,4,4,5,5}; + boolean res = s.isPossible(input); + System.out.println(res); + } + + + + +} diff --git a/src/main/java/split_array_largest_sum/SplitArrayLargestSum.java b/src/main/java/split_array_largest_sum/SplitArrayLargestSum.java new file mode 100644 index 0000000..4c654d4 --- /dev/null +++ b/src/main/java/split_array_largest_sum/SplitArrayLargestSum.java @@ -0,0 +1,39 @@ +package split_array_largest_sum; + +/** + * Created by lxie on 1/19/18. + */ +public class SplitArrayLargestSum { + + public class Solution { + public int splitArray(int[] nums, int m) { + int n = nums.length; + int[] sums = new int[n+1]; + int[][] dp = new int[m+1][n+1]; + for (int i=0; i<=m; ++i) + for(int j=0; j<=n; ++j) + dp[i][j] = Integer.MAX_VALUE; + + dp[0][0] = 0; + for (int i = 1; i <= n; ++i) { + sums[i] = sums[i - 1] + nums[i - 1]; + } + for (int i = 1; i <= m; ++i) { + for (int j = 1; j <= n; ++j) { + for (int k = i - 1; k < j; ++k) { + int val = Integer.max(dp[i - 1][k], sums[j] - sums[k]); + dp[i][j] = Integer.min(dp[i][j], val); + } + } + } + return dp[m][n]; + + } + } + + public static class UnitTest { + + } + + +} diff --git a/src/main/java/sqrt_x/SqrtX.java b/src/main/java/sqrt_x/SqrtX.java index 340fdda..256a1fe 100644 --- a/src/main/java/sqrt_x/SqrtX.java +++ b/src/main/java/sqrt_x/SqrtX.java @@ -3,13 +3,19 @@ public class SqrtX { public class Solution { - public int sqrt(int a) { - double x = 1.0; - while (Math.abs(x * x - a) > 10E-6) { - x = (x + a / x) / 2; + + public int SqrtX(int x) { + long left = 0, right = (x / 2) + 1; + while (left <= right) { + long mid = (left + right) / 2; + long sq = mid * mid; + if (sq == x) return (int) mid; + else if (sq < x) left = mid + 1; + else right = mid - 1; } - return (int) x; + return (int) right; } + } public static class UnitTest { diff --git a/src/main/java/stream_disjoint_intervals/StreamAsDisjointIntervals.java b/src/main/java/stream_disjoint_intervals/StreamAsDisjointIntervals.java new file mode 100644 index 0000000..4ee1ed1 --- /dev/null +++ b/src/main/java/stream_disjoint_intervals/StreamAsDisjointIntervals.java @@ -0,0 +1,61 @@ +package stream_disjoint_intervals; + +import common.Interval; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by lxie on 1/11/18. + */ +public class StreamAsDisjointIntervals { + + /** + * Definition for an interval. + * public class Interval { + * int start; + * int end; + * Interval() { start = 0; end = 0; } + * Interval(int s, int e) { start = s; end = e; } + * } + */ + class SummaryRanges { + + private List v = new ArrayList<>(); + + /** Initialize your data structure here. */ + public SummaryRanges() { + + } + + public void addNum(int val) { + Interval cur = new Interval(val, val); + List res = new ArrayList<>(); + int pos = 0; + for (Interval a : v) { + if (cur.end + 1 < a.start) { + res.add(a); + } else if (cur.start > a.end + 1) { + res.add(a); + ++pos; + } else { + cur.start = Integer.min(cur.start, a.start); + cur.end = Integer.max(cur.end, a.end); + } + } + res.add(pos, cur); + v = res; + } + + public List getIntervals() { + return v; + } + } + + + public static class UnitTest { + + } + + +} diff --git a/src/main/java/string_to_integer_atoi/StringtoIntegeratoi.java b/src/main/java/string_to_integer_atoi/StringtoIntegeratoi.java index 01401a1..c7a402e 100644 --- a/src/main/java/string_to_integer_atoi/StringtoIntegeratoi.java +++ b/src/main/java/string_to_integer_atoi/StringtoIntegeratoi.java @@ -5,40 +5,21 @@ public class StringtoIntegeratoi { public class Solution { public int atoi(String str) { - int index = 0; - while (index < str.length() - && Character.isWhitespace(str.charAt(index))) { - index++; + if (str.isEmpty()) return 0; + int sign = 1, base = 0, i = 0, n = str.length(); + while (i < n && str.charAt(i) == ' ') ++i; + if (str.charAt(i) == '+' || str.charAt(i) == '-') { + sign = (str.charAt(i++) == '+') ? 1 : -1; } - if (index == str.length()) { - return 0; - } - boolean negative = false; - if (str.charAt(index) == '+') { - index++; - } else if (str.charAt(index) == '-') { - index++; - negative = true; - } - long ans = 0; - while (index < str.length() && Character.isDigit(str.charAt(index))) { - ans = ans * 10 + str.charAt(index) - '0'; - if (ans > Integer.MAX_VALUE + 1L) { - break; - } - index++; - } - if (negative) { - ans = -ans; - if (ans < Integer.MIN_VALUE) { - return Integer.MIN_VALUE; - } - } else { - if (ans > Integer.MAX_VALUE) { - return Integer.MAX_VALUE; + while (i < n && str.charAt(i) >= '0' && str.charAt(i) <= '9') { + if (base > Integer.MAX_VALUE / 10 || (base == Integer.MAX_VALUE / 10 && + str.charAt(i) - '0' > 7)) { + return (sign == 1) ? Integer.MAX_VALUE : Integer.MIN_VALUE; } + base = 10 * base + (str.charAt(i++) - '0'); } - return (int) ans; + return base * sign; + } } diff --git a/src/main/java/strobogrammatic_number/StrobogrammaticNumber.java b/src/main/java/strobogrammatic_number/StrobogrammaticNumber.java new file mode 100644 index 0000000..5cfb582 --- /dev/null +++ b/src/main/java/strobogrammatic_number/StrobogrammaticNumber.java @@ -0,0 +1,37 @@ +package strobogrammatic_number; + +/** + * Created by lxie on 2/12/18. + */ +public class StrobogrammaticNumber { + + public class Solution { + + boolean isStrobogrammatic(String num) { + char[] numi = num.toCharArray(); + int l = 0, r = numi.length - 1; + while (l <= r) { + if (numi[l] == numi[r]) { + if (numi[l] != '1' && numi[l] != '0' && numi[l] != '8'){ + return false; + } + } else { + // must be 6 o 9 if not equal + if ((numi[l] != '6' || numi[r] != '9') && (numi[l] != '9' || numi[r] != '6')) { + return false; + } + } + ++l; --r; + } + return true; + } + + + + } + + public static class UnitTest { + + } + +} diff --git a/src/main/java/strobogrammatic_number_ii/StrobogrammaticNumberII.java b/src/main/java/strobogrammatic_number_ii/StrobogrammaticNumberII.java new file mode 100644 index 0000000..bc01f92 --- /dev/null +++ b/src/main/java/strobogrammatic_number_ii/StrobogrammaticNumberII.java @@ -0,0 +1,41 @@ +package strobogrammatic_number_ii; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * Created by lxie on 3/15/18. + */ +public class StrobogrammaticNumberII { + + public static class Solution { + + public List findStrobogrammatic(int n) { + return find(n, n); + } + + private List find(int m, int n) { + if (m == 0) return new ArrayList(Arrays.asList("")); + if (m == 1) return new ArrayList(Arrays.asList("0", "1", "8")); + List t = find(m - 2, n); + List res = new ArrayList<>(); + for (String a : t) { + if (m != n) res.add("0" + a + "0"); // cannot add 0 when m = n + res.add("1" + a + "1"); + res.add("6" + a + "9"); + res.add("8" + a + "8"); + res.add("9" + a + "6"); + } + return res; + } + + } + + public static void main(String[] args) { + System.out.println("this is for test"); + Solution s = new Solution(); + System.out.println(s.findStrobogrammatic(3)); + } + +} diff --git a/src/main/java/strobogrammatic_number_iii/StrobogrammaticNumberIII.java b/src/main/java/strobogrammatic_number_iii/StrobogrammaticNumberIII.java new file mode 100644 index 0000000..8ae997e --- /dev/null +++ b/src/main/java/strobogrammatic_number_iii/StrobogrammaticNumberIII.java @@ -0,0 +1,40 @@ +package strobogrammatic_number_iii; + +/** + * Created by lxie on 3/16/18. + */ +public class StrobogrammaticNumberIII { + + public static class Solution { + public int strobogrammaticInRange(String low, String high) { + int[] res = new int[1]; + find(low, high, "", res); + find(low, high, "0", res); + find(low, high, "1", res); + find(low, high, "8", res); + return res[0]; + } + + private void find(String low, String high, String w, int[] res) { + if (w.length() >= low.length() && w.length() <= high.length()) { + if ((w.length() == low.length() && w.compareTo(low) < 0) || + (w.length() == high.length() && w.compareTo(high) > 0)) { + return; + } + if (!(w.length() > 1 && w.toCharArray()[0] == '0')) ++res[0]; + } + if (w.length() + 2 > high.length()) return; + find(low, high, "0" + w + "0", res); + find(low, high, "1" + w + "1", res); + find(low, high, "6" + w + "9", res); + find(low, high, "8" + w + "8", res); + find(low, high, "9" + w + "6", res); + } + } + + public static void main(String[] args) { + System.out.println("this is for test"); + Solution s = new Solution(); + System.out.println(s.strobogrammaticInRange("50", "100")); + } +} diff --git a/src/main/java/student_attendance_record_ii/StudentAttendanceRecordII.java b/src/main/java/student_attendance_record_ii/StudentAttendanceRecordII.java new file mode 100644 index 0000000..cf8ea28 --- /dev/null +++ b/src/main/java/student_attendance_record_ii/StudentAttendanceRecordII.java @@ -0,0 +1,34 @@ +package student_attendance_record_ii; + +/** + * Created by lxie on 9/15/18. + */ +public class StudentAttendanceRecordII { + + public class Solution { + + public int checkRecord(int n) { + int M = 1000000007; + long[] P = new long[n + 1]; + long[] PorL = new long[n + 1]; + + P[0] = 1; PorL[0] = 1; PorL[1] = 2; + for (int i = 1; i <= n; ++i) { + P[i] = PorL[i - 1]; + if (i > 1) PorL[i] = (P[i] + P[i - 1] + P[i - 2]) % M; + } + long res = PorL[n]; + // now we consider A + for (int i = 0; i < n; ++i) { + long t = (PorL[i] * PorL[n - 1 - i]) % M; + res = (res + t) % M; + } + return (int) res; + } + } + + public class UnitTest { + + + } +} diff --git a/src/main/java/subarray_sum_equal_k/SubarraySumEqualsK.java b/src/main/java/subarray_sum_equal_k/SubarraySumEqualsK.java new file mode 100644 index 0000000..83349e6 --- /dev/null +++ b/src/main/java/subarray_sum_equal_k/SubarraySumEqualsK.java @@ -0,0 +1,37 @@ +package SubarraySumEqualsK; + +import java.util.HashMap; +import java.util.Map; + +/** + * Created by lxie on 9/14/18. + */ +public class SubarraySumEqualsK { + + public class Solution { + + public int subarraySum(int[] nums, int k) { + int res = 0, sum = 0, n = nums.length; + Map m = new HashMap<>(); + m.put(0, 1); + + for (int i = 0; i < n; ++i) { + sum += nums[i]; + if (m.containsKey(sum - k)) { + res += m.get(sum - k); + } + if (m.containsKey(sum)) { + m.put(sum, m.get(sum)+1); + } else { + m.put(sum, 1); + } + } + return res; + } + } + + public class UnitTest { + + } + +} diff --git a/src/main/java/subsets/Subsets.java b/src/main/java/subsets/Subsets.java index 9318484..e35a04e 100644 --- a/src/main/java/subsets/Subsets.java +++ b/src/main/java/subsets/Subsets.java @@ -2,27 +2,26 @@ import java.util.ArrayList; import java.util.Arrays; +import java.util.List; public class Subsets { public class Solution { - public ArrayList> subsets(int[] S) { - Arrays.sort(S); - ArrayList> subsets = new ArrayList>(); - for (int i = 0; i < 1 << S.length; i++) { - ArrayList subset = new ArrayList(); - int n = i; - int idx = 0; - while (n > 0) { - if ((n & 1) == 1) { - subset.add(S[idx]); - } - n >>= 1; - idx++; - } - subsets.add(subset); + public List> subsets(int[] nums) { + List> res = new ArrayList<>(); + List out = new ArrayList<>(); + Arrays.sort(nums); + getSubsets(nums, 0, out, res); + return res; + } + + private void getSubsets(int[] nums, int pos, List out, List> res) { + res.add(new ArrayList<>(out)); + for (int i = pos; i < nums.length; ++i) { + out.add(nums[i]); + getSubsets(nums, i + 1, out, res); + out.remove(out.size()-1); } - return subsets; } } diff --git a/src/main/java/subsets_ii/SubsetsII.java b/src/main/java/subsets_ii/SubsetsII.java index bc8e6d6..da542c5 100644 --- a/src/main/java/subsets_ii/SubsetsII.java +++ b/src/main/java/subsets_ii/SubsetsII.java @@ -2,29 +2,28 @@ import java.util.ArrayList; import java.util.Arrays; +import java.util.List; public class SubsetsII { public class Solution { - public ArrayList> subsetsWithDup(int[] num) { - Arrays.sort(num); - ArrayList> subsets = new ArrayList>(); - subsets.add(new ArrayList()); - int last = 1; - for (int i = 0; i < num.length; i++) { - int start = 0; - if (i != 0 && num[i] == num[i - 1]) { - start = last; - } - last = subsets.size(); - for (int j = start; j < last; j++) { - ArrayList subset = new ArrayList( - subsets.get(j)); - subset.add(num[i]); - subsets.add(subset); - } + + public List> subsetsWithDup(int[] nums) { + List> res = new ArrayList<>(); + List out = new ArrayList<>(); + Arrays.sort(nums); + getSubsets(nums, 0, out, res); + return res; + } + + private void getSubsets(int[] nums, int pos, List out, List> res) { + res.add(new ArrayList<>(out)); + for (int i = pos; i < nums.length; ++i) { + out.add(nums[i]); + getSubsets(nums, i + 1, out, res); + out.remove(out.size()-1); + while (i + 1 < nums.length && nums[i] == nums[i+1]) ++i; } - return subsets; } } diff --git a/src/main/java/substring_with_concatenation_of_all_words/SubstringwithConcatenationofAllWords.java b/src/main/java/substring_with_concatenation_of_all_words/SubstringwithConcatenationofAllWords.java new file mode 100644 index 0000000..d30a45c --- /dev/null +++ b/src/main/java/substring_with_concatenation_of_all_words/SubstringwithConcatenationofAllWords.java @@ -0,0 +1,52 @@ +package substring_with_concatenation_of_all_words; + +import java.util.ArrayList; +import java.util.HashMap; + +public class SubstringwithConcatenationofAllWords { + + public class Solution { + public ArrayList findSubstring(String S, String[] L) { + ArrayList ans = new ArrayList(); + if (S.isEmpty() || L.length == 0) return ans; + HashMap dict = new HashMap(); + for (String l : L) { + Integer count = dict.get(l); + if (count == null) { + dict.put(l, 1); + } else { + dict.put(l, count + 1); + } + } + int wordSize = L[0].length(); + int windowSize = wordSize * L.length; + + for (int i = 0; i <= S.length() - windowSize; i++) { + HashMap temp = new HashMap(); + boolean skip = false; int j = 0; + for (; j < windowSize; j += wordSize) { + String word = S.substring(i + j, i + j + wordSize); + Integer count = dict.get(word); + if (count == null) { + break; + } + Integer tempCount = temp.get(word); + if (tempCount == null) { + temp.put(word, 1); + } else if (count == tempCount) { + break; + } else { + temp.put(word, tempCount + 1); + } + } + if (j == windowSize) { + ans.add(i); + } + } + return ans; + } + } + + public static class UnitTest { + } +} diff --git a/src/main/java/sudoku_solver/SudokuSolver.java b/src/main/java/sudoku_solver/SudokuSolver.java new file mode 100644 index 0000000..43a9bdc --- /dev/null +++ b/src/main/java/sudoku_solver/SudokuSolver.java @@ -0,0 +1,65 @@ +package sudoku_solver; + +import java.util.Arrays; + +public class SudokuSolver { + + public class Solution { + public boolean solveSudoku(char[][] board){ + for(int i = 0; i < 9; i++){ + for(int j = 0; j < 9; j++){ + if(board[i][j] != '.') + continue; + for(char k = '1'; k <= '9'; k++){ + board[i][j] = k; + if(checkValid(board,i,j)){ + if(solveSudoku(board)) + return true; + } + board[i][j] = '.'; + } + return false; + } + } + return true; + } + + private boolean checkValid(char[][] board, int x, int y){ + boolean[] flags = new boolean[9]; + for(int i = 0; i < 9; ++i) + if(board[x][i] >= '1' && board[x][i] <= '9'){ + if(!flags[board[x][i] - '1']) + flags[board[x][i] - '1'] = true; + else + return false; + } + Arrays.fill(flags, false); + for(int i = 0; i < 9; ++i) + if(board[i][y] >= '1' && board[i][y] <= '9'){ + if(!flags[board[i][y] - '1']) + flags[board[i][y] - '1'] = true; + else + return false; + } + int xx = x/3*3; + int yy = y/3*3; + Arrays.fill(flags, false); + for(int i = 0; i < 3; ++i) + for(int j = 0; j < 3; ++j) + if(board[xx+i][yy+j] >= '1' && board[xx+i][yy+j]<= '9'){ + if(!flags[board[xx+i][yy+j]-'1']) + flags[board[xx+i][yy+j]-'1'] = true; + else + return false; + } + + return true; + } + + + } + + public static class UnitTest { + + } +} diff --git a/src/main/java/sum_of_left_leaves/SumOfLeftLeaves.java b/src/main/java/sum_of_left_leaves/SumOfLeftLeaves.java new file mode 100644 index 0000000..560d1c3 --- /dev/null +++ b/src/main/java/sum_of_left_leaves/SumOfLeftLeaves.java @@ -0,0 +1,30 @@ +package sum_of_left_leaves; + +/** + * Created by lxie on 9/8/17. + */ +public class SumOfLeftLeaves { + + public class TreeNode { + int val; + TreeNode left; + TreeNode right; + TreeNode(int x) { val = x; } + } + + class Solution { + public int sumOfLeftLeaves(TreeNode root) { + if(root == null) return 0; + if(root.left != null && root.left.left == null && root.left.right == null){ + return root.left.val + sumOfLeftLeaves(root.right); + } + return sumOfLeftLeaves(root.left) + sumOfLeftLeaves(root.right); + + } + } + + public static void main(String[] args) { + System.out.println("this is for test"); + } + +} diff --git a/src/main/java/summary_ranges/SummaryRanges.java b/src/main/java/summary_ranges/SummaryRanges.java new file mode 100644 index 0000000..cd0053f --- /dev/null +++ b/src/main/java/summary_ranges/SummaryRanges.java @@ -0,0 +1,30 @@ +package summary_ranges; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by lxie on 2/28/18. + */ +public class SummaryRanges { + + public class Solution { + public List summaryRanges(int[] nums) { + List res = new ArrayList<>(); + int i = 0, n = nums.length; + while (i < n) { + int j = 1; + while (i + j < n && nums[i + j] - nums[i] == j) ++j; + res.add(j <= 1 ? Integer.toString(nums[i]) : Integer.toString(nums[i]) + + "->" + Integer.toString(nums[i + j - 1])); + i += j; + } + return res; + } + } + + public static class UnitTest { + + } + +} diff --git a/src/main/java/super_ugly_number/SuperUglyNumber.java b/src/main/java/super_ugly_number/SuperUglyNumber.java new file mode 100644 index 0000000..3af10e8 --- /dev/null +++ b/src/main/java/super_ugly_number/SuperUglyNumber.java @@ -0,0 +1,34 @@ +package super_ugly_number; + +/** + * Created by lxie on 7/2/18. + */ +public class SuperUglyNumber { + + public class Solution { + + public int nthSuperUglyNumber(int n, int[] primes) { + int[] dp = new int[n]; for (int i=0; i= rows || y >= columns; - } public void solve(char[][] board) { - if (board.length == 0 || board[0].length == 0) { - return; - } - int rows = board.length; - int columns = board[0].length; - - ArrayDeque stack = new ArrayDeque(); - for (int i = 0; i < rows; i++) { - stack.offerLast(new Pos(i, 0)); - stack.offerLast(new Pos(i, columns - 1)); - } - for (int i = 0; i < columns; i++) { - stack.offerLast(new Pos(0, i)); - stack.offerLast(new Pos(rows - 1, i)); + for (int i = 0; i < board.length; ++i) { + for (int j = 0; j < board[i].length; ++j) { + if ((i == 0 || i == board.length - 1 || j == 0 || + j == board[i].length - 1) && board[i][j] == 'O') + solveDFS(board, i, j); + } } - - while (!stack.isEmpty()) { - Pos pos = stack.removeLast(); - int x = pos.x; - int y = pos.y; - if (isOutOfBound(x, y, rows, columns) || board[x][y] != 'O') { - continue; + for (int i = 0; i < board.length; ++i) { + for (int j = 0; j < board[i].length; ++j) { + if (board[i][j] == 'O') board[i][j] = 'X'; + if (board[i][j] == '$') board[i][j] = 'O'; } - board[x][y] = 'N'; - stack.offerLast(new Pos(x - 1, y)); - stack.offerLast(new Pos(x + 1, y)); - stack.offerLast(new Pos(x, y - 1)); - stack.offerLast(new Pos(x, y + 1)); } + } - for (int i = 0; i < rows; i++) { - for (int j = 0; j < columns; j++) { - if (board[i][j] == 'O') { - board[i][j] = 'X'; - } else if (board[i][j] == 'N') { - board[i][j] = 'O'; - } - } + private void solveDFS(char[][]board, int i, int j) { + if (board[i][j] == 'O') { + board[i][j] = '$'; + if (i > 0 && board[i - 1][j] == 'O') + solveDFS(board, i - 1, j); + if (j < board[i].length - 1 && board[i][j + 1] == 'O') + solveDFS(board, i, j + 1); + if (i < board.length - 1 && board[i + 1][j] == 'O') + solveDFS(board, i + 1, j); + if (j > 1 && board[i][j - 1] == 'O') + solveDFS(board, i, j - 1); } } } diff --git a/src/main/java/symmetric_tree/SymmetricTree.java b/src/main/java/symmetric_tree/SymmetricTree.java new file mode 100644 index 0000000..422f3ce --- /dev/null +++ b/src/main/java/symmetric_tree/SymmetricTree.java @@ -0,0 +1,62 @@ +package symmetric_tree; + +import java.util.LinkedList; + +import common.TreeNode; + +public class SymmetricTree { + + public class Solution { + private boolean isSymmetric(TreeNode left, TreeNode right) { + if (left == null && right == null) { + return true; + } + if (left == null || right == null) { + return left == right; + } + return left.val == right.val && isSymmetric(left.left, right.right) + && isSymmetric(left.right, right.left); + } + + public boolean isSymmetric(TreeNode root) { + if (root == null) { + return true; + } + return isSymmetric(root.left, root.right); + } + } + + public class SolutionWithIterative { + public boolean isSymmetric(TreeNode root) { + if (root == null) { + return true; + } + LinkedList lefts = new LinkedList(); + LinkedList rights = new LinkedList(); + lefts.add(root.left); + rights.add(root.right); + while (!lefts.isEmpty() && !rights.isEmpty()) { + TreeNode left = lefts.poll(); + TreeNode right = rights.poll(); + if (left == null && right == null) { + continue; + } + if (left == null || right == null) { + return false; + } + if (left.val != right.val) { + return false; + } + lefts.add(left.left); + lefts.add(left.right); + rights.add(right.right); + rights.add(right.left); + } + return lefts.isEmpty() && rights.isEmpty(); + } + } + + public static class UnitTest { + + } +} diff --git a/src/main/java/system_dependencies/SystemDependencies.java b/src/main/java/system_dependencies/SystemDependencies.java new file mode 100644 index 0000000..28a86e2 --- /dev/null +++ b/src/main/java/system_dependencies/SystemDependencies.java @@ -0,0 +1,187 @@ +package system_dependencies; + +import java.util.*; + +import static system_dependencies.SystemDependencies.FileStatus.EXPLICITYLY_INSTALLED; +import static system_dependencies.SystemDependencies.FileStatus.IMPLICITYLY_INSTALLED; +import static system_dependencies.SystemDependencies.FileStatus.NOT_INSTALLED; + +/** + * The SystemDependencies program implements an application that + * supports file dependencies during file installations and + * removals. + * + * @author Liang Xie + * @version 1.0 + * @since 2018-09-12 + */ +public class SystemDependencies { + + public enum FileStatus + { + NOT_INSTALLED, EXPLICITYLY_INSTALLED, IMPLICITYLY_INSTALLED; + } + + private final int maxn =10000; // maximum 10000 files in total + private int cnt = 0; + /* a mapping between file name and id */ + public Map name2id = new HashMap<>(); + + public String[] name = new String[maxn]; + + /* file dependency graphs - depend on and depended on */ + public List> depend = new ArrayList<>(); // depend on + public List> depend2 = new ArrayList<>(); // depended on + + /* status array for the files */ + public FileStatus[] status = new FileStatus[maxn]; + + /* installed files in a list */ + public List installed = new ArrayList<>(); + + /* constructor */ + public SystemDependencies() { + for (int i = 0; i < maxn; ++i) { + this.depend.add(new ArrayList<>()); + this.depend2.add(new ArrayList<>()); + } + Arrays.fill(status, NOT_INSTALLED); + Arrays.fill(name, ""); + } + + /** + * This method is used to obtain an integer ID given the file + * name string. + * @param itemName file name string + * @return int returns an integer ID. + */ + public int getID(String itemName) { + if(!name2id.containsKey(itemName)) { + // create an integer ID if does not exist + name[++cnt] = itemName; + name2id.put(itemName, cnt); + } + return name2id.get(itemName); + + } + + /** + * This method is used to check if a file is needed by dependants + * @param item file ID + * @return boolean returns true if there is dependants on the file. + */ + public boolean needed(int item) { + for(int i = 0; i < depend2.get(item).size();i++) + if(status[depend2.get(item).get(i)] != NOT_INSTALLED) return true; + return false; + } + + /** + * This method is used to install a file given the current dependencies + * @param item file ID + * @param toplevel whether the file is at top-level + * @return void + */ + public void install(int item, boolean toplevel) { + if(status[item] == NOT_INSTALLED) { + // for all dependents call install (not toplevel) + for(int i = 0; i < depend.get(item).size();i++) { + install(depend.get(item).get(i), false); + } + System.out.println(" Installing " + name[item]); + // toplevel - explicitly installed + status[item] = toplevel ? EXPLICITYLY_INSTALLED : IMPLICITYLY_INSTALLED; + installed.add(item); + } + } + + /** + * This method is used to remove a file given the current dependencies + * @param item file ID + * @param toplevel whether the file is at top-level + * @return void + */ + public void remove(int item, boolean toplevel) { + /* remove the file that has no dependents and is at toplevel or + implicitly installed */ + if((toplevel || status[item] == IMPLICITYLY_INSTALLED) &&!needed(item)) { + status[item] = NOT_INSTALLED; + installed.remove(new Integer(item)); + System.out.println(" Removing " + name[item]); + + // for all dependents call remove (not toplevel) + for(int i = 0; i < depend.get(item).size();i++) { + remove(depend.get(item).get(i), false); + } + } + } + + /** + * This method prints out installed files according to the + * installation order + */ + public void list() { + for(int i = 0; i < installed.size(); i++) { + System.out.println(" " + name[installed.get(i)]); + } + } + + public static void main(String[] args) { + SystemDependencies sdep = new SystemDependencies(); + String line = "", cmd = ""; + + Scanner scanner = new Scanner(System.in); + while(true) { + line = scanner.nextLine(); + System.out.println(line); + String[] params = line.split(" "); + + /* cmd is END */ + if(params[0].equals("END")) break; + + /* cmd is LIST */ + if(params[0].equals("LIST")) sdep.list(); + else { + int i1 = sdep.getID(params[1]); + /* cmd is DEPEND */ + if(params[0].equals("DEPEND")) { + // add dependencies to the graphs + for(int i = 2; i < params.length; ++i) { + int i2 = sdep.getID(params[i]); + sdep.depend.get(i1).add(i2); + sdep.depend2.get(i2).add(i1); + } + } + /* cmd is INSTALL */ + else if(params[0].equals("INSTALL")) { + if(sdep.status[i1] != NOT_INSTALLED) + System.out.println(" " + params[1] + " is already installed."); + else + sdep.install(i1, true); + } + /* cmd is REMOVE */ + else { + if(sdep.status[i1] == NOT_INSTALLED) + System.out.println(" " + params[1] + " is not installed."); + else if(sdep.needed(i1)) + System.out.println(" " + params[1] +" is still needed."); + else sdep.remove(i1, true); + + } + + } + } + } + + + + + + + + + + + + +} diff --git a/src/main/java/system_dependencies/SystemDependenciesUnitTest.java b/src/main/java/system_dependencies/SystemDependenciesUnitTest.java new file mode 100644 index 0000000..16cc558 --- /dev/null +++ b/src/main/java/system_dependencies/SystemDependenciesUnitTest.java @@ -0,0 +1,139 @@ +package system_dependencies; + +import org.junit.Assert; +import org.junit.Test; + +import static system_dependencies.SystemDependencies.FileStatus.EXPLICITYLY_INSTALLED; +import static system_dependencies.SystemDependencies.FileStatus.IMPLICITYLY_INSTALLED; +import static system_dependencies.SystemDependencies.FileStatus.NOT_INSTALLED; + +/** + * Created by lxie on 9/12/18. + */ +public class SystemDependenciesUnitTest { + + SystemDependencies sdep = new SystemDependencies(); + + public SystemDependenciesUnitTest() { + setupDependencies(); + } + + @Test + public void testGetID(){ + // first id is TELNET(1) + int id = sdep.getID("TELNET"); + Assert.assertEquals(id, 1); + + // last id is HTML(6), 6 files in total + id = sdep.getID("HTML"); + Assert.assertEquals(id, 6); + + // add a new id = 7 for FIREWALL(7) + id = sdep.getID("FIREWALL"); + Assert.assertEquals(id, 7); + } + + @Test + public void testNeeded(){ + /* HTML(6) is needed by BROWSER(5) */ + sdep.install(5, true); + boolean res = sdep.needed(6); + Assert.assertEquals(res, true); + + /* FIREWALL(7) is not needed by anyone */ + res = sdep.needed(7); + Assert.assertEquals(res, false); + + /* a non-existing file id = 15 is not needed */ + res = sdep.needed(15); + Assert.assertEquals(res, false); + } + + @Test + public void testInstall(){ + /* install NETCARD(3) -> NETCARD(3) */ + sdep.install(3, true); + Assert.assertEquals(sdep.status[3], EXPLICITYLY_INSTALLED); + Assert.assertEquals(sdep.installed.contains(3), true); + + /* install TELNET(1) -> TCPIP(2), TELNET(1) */ + sdep.install(1, true); + Assert.assertEquals(sdep.status[2], IMPLICITYLY_INSTALLED); + Assert.assertEquals(sdep.installed.contains(2), true); + Assert.assertEquals(sdep.status[1], EXPLICITYLY_INSTALLED); + Assert.assertEquals(sdep.installed.contains(1), true); + + /* install a new file foo(7) -> foo(7) */ + int id = sdep.getID("foo"); + sdep.install(7, true); + Assert.assertEquals(sdep.status[7], EXPLICITYLY_INSTALLED); + Assert.assertEquals(sdep.installed.contains(7), true); + + /* install a file that already exists, nothing should change */ + sdep.install(7, true); + Assert.assertEquals(sdep.status[7], EXPLICITYLY_INSTALLED); + Assert.assertEquals(sdep.installed.contains(7), true); + + } + + @Test + public void testRemove(){ + + testInstall(); + + /* remove NETCARD(3) -> still needed by others */ + sdep.remove(3, true); + Assert.assertEquals(sdep.status[3], EXPLICITYLY_INSTALLED); + Assert.assertEquals(sdep.installed.contains(3), true); + + /* remove TELNET(1) -> removed TELNET(1), TCPIP(2)*/ + sdep.remove(1, true); + Assert.assertEquals(sdep.status[1], NOT_INSTALLED); + Assert.assertEquals(sdep.installed.contains(1), false); + // TCPIP implicitely installed is also removed (not needed by others) + Assert.assertEquals(sdep.status[2], NOT_INSTALLED); + Assert.assertEquals(sdep.installed.contains(2), false); + + /* remove foo(7) -> removed foo(7) */ + sdep.remove(7, true); + Assert.assertEquals(sdep.status[1], NOT_INSTALLED); + Assert.assertEquals(sdep.installed.contains(7), false); + + } + + /* this function sets up the dependency graphs */ + public void setupDependencies(){ + String[] depends = { "DEPEND TELNET TCPIP NETCARD", + "DEPEND TCPIP NETCARD", + "DEPEND DNS TCPIP NETCARD", + "DEPEND BROWSER TCPIP HTML"}; + for (String line : depends) { + String[] params = line.split(" "); + int i1 = sdep.getID(params[1]); + /* cmd is DEPEND */ + if(params[0].equals("DEPEND")) { + // add dependencies to the graphs + for(int i = 2; i < params.length; ++i) { + int i2 = sdep.getID(params[i]); + sdep.depend.get(i1).add(i2); + sdep.depend2.get(i2).add(i1); + } + } + } + + } + + + + + + + + + + + + + + +} diff --git a/src/main/java/target_sum/TargetSum.java b/src/main/java/target_sum/TargetSum.java new file mode 100644 index 0000000..f1e70b3 --- /dev/null +++ b/src/main/java/target_sum/TargetSum.java @@ -0,0 +1,39 @@ +package target_sum; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Created by lxie on 9/21/18. + */ +public class TargetSum { + + public class Solution { + + public int findTargetSumWays(int[] nums, int S) { + List> dp = new ArrayList<>(); + for (int i = 0; i< nums.length; ++i) + dp.add(new HashMap<>()); + return helper(nums, S, 0, dp); + } + + private int helper(int[] nums, int sum, int start, List> dp) { + if (start == nums.length) return sum == 0 ? 1 : 0; + if (dp.get(start).containsKey(sum)) return dp.get(start).get(sum); + int cnt1 = helper(nums, sum - nums[start], start + 1, dp); + int cnt2 = helper(nums, sum + nums[start], start + 1, dp); + dp.get(start).put(sum, cnt1 + cnt2); + return cnt1 + cnt2; + } + + } + + public class UnitTest { + + + + } + +} diff --git a/src/main/java/task_scheduler/TaskScheduler.java b/src/main/java/task_scheduler/TaskScheduler.java new file mode 100644 index 0000000..f056cf3 --- /dev/null +++ b/src/main/java/task_scheduler/TaskScheduler.java @@ -0,0 +1,47 @@ +package task_scheduler; + +import java.util.*; + +/** + * Created by lxie on 9/24/18. + */ +public class TaskScheduler { + + public class Solution { + + public int leastInterval(char[] tasks, int n) { + int res = 0, cycle = n + 1; + Map m = new HashMap<>(); + PriorityQueue q = new PriorityQueue<>(100, Collections.reverseOrder()); + for (char c : tasks) { + if (m.containsKey(c)) + m.put(c, m.get(c)+1); + else + m.put(c, 1); + } + for (Map.Entry a : m.entrySet()) + q.add(a.getValue()); + while (!q.isEmpty()) { + int cnt = 0; + List t = new ArrayList<>(); + for (int i = 0; i < cycle; ++i) { + if (!q.isEmpty()) { + t.add(q.peek()); q.poll(); + ++cnt; + } + } + for (int d : t) { + if (--d > 0) q.add(d); + } + res += q.isEmpty() ? cnt : cycle; + } + return res; + } + } + + public class UnitTest { + + + } + +} diff --git a/src/main/java/text_justification/TextJustification.java b/src/main/java/text_justification/TextJustification.java new file mode 100644 index 0000000..193fe84 --- /dev/null +++ b/src/main/java/text_justification/TextJustification.java @@ -0,0 +1,47 @@ +package text_justification; + +import java.util.ArrayList; +import java.util.List; + +public class TextJustification { + + public class Solution { + public List fullJustify(String[] words, int maxWidth) { + List res = new ArrayList<>(); + int i = 0; + while (i < words.length) { + int j = i, len = 0; + while (j < words.length && len + words[j].length() + j - i <= maxWidth) { + len += words[j++].length(); + } + String out = ""; + int space = maxWidth - len; + for (int k = i; k < j; ++k) { + out += words[k]; + if (space > 0) { + int tmp; + if (j == words.length) { + if (j - k == 1) tmp = space; + else tmp = 1; + } else { + if (j - k - 1 > 0) { + if (space % (j - k - 1) == 0) tmp = space / (j - k - 1); + else tmp = space / (j - k - 1) + 1; + } else tmp = space; + } + //Strings.padEnd(out, tmp, ' '); + for(int a=0; a= 0 && x < m && y >= 0 && y < n && maze[x][y] != 1) { + x += dir[0]; y += dir[1]; + } + x -= dir[0]; y -= dir[1]; + if (maze[x][y] != -1) { + res |= helper(maze, dp, x, y, di, dj); // either way + } + } + dp[i][j] = res ? 1 : 0; + return res; + } + } + + public class UnitTest { + + + + } + +} diff --git a/src/main/java/the_maze_ii/TheMazeII.java b/src/main/java/the_maze_ii/TheMazeII.java new file mode 100644 index 0000000..0bfbce8 --- /dev/null +++ b/src/main/java/the_maze_ii/TheMazeII.java @@ -0,0 +1,51 @@ +package the_maze_ii; + +import java.util.Arrays; + +/** + * Created by lxie on 8/27/18. + */ +public class TheMazeII { + + public class Solution { + + public int[][] dirs = {{0,-1},{-1,0},{0,1},{1,0}}; + + public int shortestDistance(int[][] maze, int[] start, int[] destination) { + int m = maze.length, n = maze[0].length; + int[][] dists = new int[m][n]; + for (int[] a : dists) Arrays.fill(a, Integer.MAX_VALUE); + + dists[start[0]][start[1]] = 0; + helper(maze, start[0], start[1], destination, dists); + int res = dists[destination[0]][destination[1]]; + return (res == Integer.MAX_VALUE) ? -1 : res; + } + + private void helper(int[][] maze, int i, int j, int[] destination, int[][] dists) { + if (i == destination[0] && j == destination[1]) return; + int m = maze.length, n = maze[0].length; + for (int[] d : dirs) { + int x = i, y = j, dist = dists[x][y]; + while (x >= 0 && x < m && y >= 0 && y < n && maze[x][y] == 0) { + x += d[0]; + y += d[1]; + ++dist; + } + x -= d[0]; + y -= d[1]; + --dist; + if (dists[x][y] > dist) { + dists[x][y] = dist; + helper(maze, x, y, destination, dists); + } + } + } + } + + public class UnitTest{ + + } + + +} diff --git a/src/main/java/third_max_number/ThirdMaximumNumber.java b/src/main/java/third_max_number/ThirdMaximumNumber.java new file mode 100644 index 0000000..86176a0 --- /dev/null +++ b/src/main/java/third_max_number/ThirdMaximumNumber.java @@ -0,0 +1,31 @@ +package third_max_number; + +/** + * Created by lxie on 1/20/18. + */ +public class ThirdMaximumNumber { + + public class Solution { + + public int thirdMax(int[] nums) { + long first = Long.MIN_VALUE, second = Long.MIN_VALUE, third = Long.MIN_VALUE; + for (int num : nums) { + if (num > first) { + third = second; + second = first; + first = num; + } else if (num > second && num < first) { + third = second; + second = num; + } else if (num > third && num < second) { + third = num; + } + } + return (third == Long.MIN_VALUE || third == second) ? (int)first : (int)third; + } + } + + public static class UnitTest { + + } +} diff --git a/src/main/java/topk_frequent_elements/TopkFrequentElements.java b/src/main/java/topk_frequent_elements/TopkFrequentElements.java new file mode 100644 index 0000000..ae4a77d --- /dev/null +++ b/src/main/java/topk_frequent_elements/TopkFrequentElements.java @@ -0,0 +1,44 @@ +package topk_frequent_elements; + +import java.util.*; + +/** + * Created by lxie on 1/10/18. + */ +public class TopkFrequentElements { + + class Solution { + public List topKFrequent(int[] nums, int k) { + List res = new ArrayList<>(); + Map m = new HashMap<>(); + PairComparator comparator = new PairComparator(); + PriorityQueue q = new PriorityQueue<>(100, comparator); + for (int a : nums) { + if (!m.containsKey(a)) m.put(a, 1); + else + m.put(a, m.get(a)+1); + }; + for (Map.Entry entry : m.entrySet()) { + q.add(new int[] {entry.getValue(), entry.getKey()}); + } + while (!q.isEmpty() && k > 0) { + res.add(q.poll()[1]); + k--; + } + + return res; + } + + class PairComparator implements Comparator { + @Override + public int compare(int[] p1, int[] p2) { + return p2[0] - p1[0]; // from high to low + } + } + } + + public static class UnitTest { + + } + +} diff --git a/src/main/java/total_hamming_distance/TotalHammingDistance.java b/src/main/java/total_hamming_distance/TotalHammingDistance.java new file mode 100644 index 0000000..4019517 --- /dev/null +++ b/src/main/java/total_hamming_distance/TotalHammingDistance.java @@ -0,0 +1,30 @@ +package total_hamming_distance; + +/** + * Created by lxie on 9/28/18. + */ +public class TotalHammingDistance { + + public class Solution { + + public int totalHammingDistance(int[] nums) { + int res = 0, n = nums.length; + for (int i = 0; i < 32; ++i) { + int cnt = 0; + for (int num : nums) { + if ((num & (1 << i)) == 1) ++cnt; + } + res += cnt * (n - cnt); + } + return res; + } + } + + public class UnitTest { + + + + } + + +} diff --git a/src/main/java/trapping_rain_water/TrappingRainWater.java b/src/main/java/trapping_rain_water/TrappingRainWater.java index 922c95e..3ca7e78 100644 --- a/src/main/java/trapping_rain_water/TrappingRainWater.java +++ b/src/main/java/trapping_rain_water/TrappingRainWater.java @@ -3,34 +3,21 @@ public class TrappingRainWater { public class Solution { - public int trap(int[] A) { - if (A.length == 0) { - return 0; + public int trap(int[] height) { + int res = 0, mx = 0, n = height.length; + int[] dp = new int[n]; + for (int i = 0; i < n; ++i) { + dp[i] = mx; + mx = Math.max(mx, height[i]); } - int maxIndex = 0; - for (int i = 1; i < A.length; i++) { - if (A[i] > A[maxIndex]) { - maxIndex = i; - } + mx = 0; + for (int i = n - 1; i >= 0; --i) { + dp[i] = Math.min(dp[i], mx); + mx = Math.max(mx, height[i]); + if (dp[i] > height[i]) res += dp[i] - height[i]; } - int height = A[0]; - int water = 0; - for (int i = 1; i < maxIndex; i++) { - if (A[i] > height) { - height = A[i]; - } else { - water += height - A[i]; - } - } - height = A[A.length - 1]; - for (int i = A.length - 2; i > maxIndex; i--) { - if (A[i] > height) { - height = A[i]; - } else { - water += height - A[i]; - } - } - return water; + return res; + } } diff --git a/src/main/java/trapping_rain_water_II/TrapRainWaterII.java b/src/main/java/trapping_rain_water_II/TrapRainWaterII.java new file mode 100644 index 0000000..f11f241 --- /dev/null +++ b/src/main/java/trapping_rain_water_II/TrapRainWaterII.java @@ -0,0 +1,66 @@ +package trapping_rain_water_II; + +import common.Pair; + +import java.util.Comparator; +import java.util.Map; +import java.util.PriorityQueue; + +/** + * Created by lxie on 9/18/17. + */ +public class TrapRainWaterII { + + static class Solution { + public int trapRainWater(int[][] heightMap) { + if(heightMap.length == 0) return 0; + int m = heightMap.length, n = heightMap[0].length, res = 0, mx = Integer.MIN_VALUE; + PairComparator comparator = new PairComparator(); + PriorityQueue> q = new PriorityQueue<>(100, comparator);; + boolean[][] visited = new boolean[m][n]; + int[][] dir = {{0,-1},{-1,0},{0,1},{1,0}}; + for (int i = 0; i < m; ++i) { + for (int j = 0; j < n; ++j) { + if (i == 0 || i == m - 1 || j == 0 || j == n - 1) { + q.offer(Pair.of(heightMap[i][j], i * n + j)); + visited[i][j] = true; + } + } + } + while (!q.isEmpty()) { + Map.Entry t = q.poll(); + int h = t.getKey(), r = t.getValue() / n, c = t.getValue() % n; + mx = Math.max(mx, h); + for (int i = 0; i < dir.length; ++i) { + int x = r + dir[i][0], y = c + dir[i][1]; + if (x < 0 || x >= m || y < 0 || y >= n || visited[x][y]) continue; + visited[x][y] = true; + if (heightMap[x][y] < mx) res += mx - heightMap[x][y]; // LC 42 + q.offer(Pair.of(heightMap[x][y], x * n + y)); + } + } + return res; + + } + + class PairComparator implements Comparator> { + @Override + public int compare(Map.Entry p1, Map.Entry p2) { + return p1.getKey() - p2.getKey(); + } + } + + } + + + public static void main(String[] args) { + System.out.println("this is for test"); + Solution sol = new Solution(); + int[][] heightMap = {{1,4,3,1,3,2}, {3,2,1,3,2,4}, {2,3,3,2,3,1}}; + int res = sol.trapRainWater(heightMap); + System.out.println(res); + } + + + +} diff --git a/src/main/java/triangle/Triangle.java b/src/main/java/triangle/Triangle.java index 72b60e0..187fca9 100644 --- a/src/main/java/triangle/Triangle.java +++ b/src/main/java/triangle/Triangle.java @@ -2,12 +2,13 @@ import java.util.ArrayList; import java.util.Collections; +import java.util.List; public class Triangle { public class Solution { - public int minimumTotal(ArrayList> triangle) { - ArrayList sum = new ArrayList(); + public int minimumTotal(List> triangle) { + List sum = new ArrayList(); if (triangle.isEmpty()) { return 0; } diff --git a/src/main/java/two_sum/TwoSum.java b/src/main/java/two_sum/TwoSum.java index 6aaa1be..5b3e842 100644 --- a/src/main/java/two_sum/TwoSum.java +++ b/src/main/java/two_sum/TwoSum.java @@ -1,51 +1,23 @@ package two_sum; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; +import java.util.HashMap; -import org.junit.Test; - -public class TwoSum { - - public class Solution { - public int[] twoSum(final int[] numbers, int target) { - List pos = new ArrayList(); - for (int i = 0; i < numbers.length; i++) { - pos.add(i); - } - Collections.sort(pos, new Comparator() { - @Override - public int compare(Integer o1, Integer o2) { - return numbers[o1] - numbers[o2]; - } - }); - - int i = 0; - int j = numbers.length - 1; - while (i < j) { - int sum = numbers[pos.get(i)] + numbers[pos.get(j)]; - if (sum < target) { - i++; - } else if (sum > target) { - j--; - } else { - int[] ans = new int[2]; - ans[0] = Math.min(pos.get(i), pos.get(j)) + 1; - ans[1] = Math.max(pos.get(i), pos.get(j)) + 1; - return ans; - } +class Solution { + public int[] twoSum(int[] nums, int target) { + HashMap m = new HashMap(); + int[] res = new int[2]; + for (int i = 0; i < nums.length; ++i) { + if (m.containsKey(target - nums[i])) { + res[0] = i; + res[1] = m.get(target - nums[i]); + break; } - // Impossible for the test set - return null; + m.put(nums[i], i); } + return res; } - public static class UnitTest { - @Test - public void test() { - new TwoSum().new Solution().twoSum(new int[] { 5, 75, 25 }, 100); - } + public class UnitTest { + } } diff --git a/src/main/java/two_sum_iv/TwoSumIV.java b/src/main/java/two_sum_iv/TwoSumIV.java new file mode 100644 index 0000000..1e33b0c --- /dev/null +++ b/src/main/java/two_sum_iv/TwoSumIV.java @@ -0,0 +1,35 @@ +package two_sum_iv; + +import common.TreeNode; + +import java.util.HashSet; +import java.util.Set; + +/** + * Created by lxie on 10/9/18. + */ +public class TwoSumIV { + + public class Solution { + + public boolean findTarget(TreeNode root, int k) { + if (root == null) return false; + Set s = new HashSet<>(); + return helper(root, k, s); + } + + private boolean helper(TreeNode node, int k, Set s) { + if (node == null) return false; + if (s.contains(k - node.val)) return true; + s.add(node.val); + return helper(node.left, k, s) || helper(node.right, k, s); + } + + } + + public class UnitTest { + + + } + +} diff --git a/src/main/java/ugly_number_ii/UglyNumberII.java b/src/main/java/ugly_number_ii/UglyNumberII.java new file mode 100644 index 0000000..7c3bd59 --- /dev/null +++ b/src/main/java/ugly_number_ii/UglyNumberII.java @@ -0,0 +1,32 @@ +package ugly_number_ii; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by lxie on 6/6/18. + */ +public class UglyNumberII { + + public class Solution { + public int nthUglyNumber(int n) { + List res = new ArrayList<>(); + res.add(1); + int i2 = 0, i3 = 0, i5 = 0; + while (res.size() < n) { + int m2 = res.get(i2) * 2, m3 = res.get(i3) * 3, m5 = res.get(i5) * 5; + int mn = Integer.min(m2, Integer.min(m3, m5)); + if (mn == m2) ++i2; + if (mn == m3) ++i3; + if (mn == m5) ++i5; + res.add(mn); + } + return res.get(res.size()-1); + } + } + + public class UnitTest { + + } + +} diff --git a/src/main/java/unique_binary_search_trees/UniqueBinarySearchTrees.java b/src/main/java/unique_binary_search_trees/UniqueBinarySearchTrees.java new file mode 100644 index 0000000..2dc4328 --- /dev/null +++ b/src/main/java/unique_binary_search_trees/UniqueBinarySearchTrees.java @@ -0,0 +1,19 @@ +package unique_binary_search_trees; + +public class UniqueBinarySearchTrees { + + public class Solution { + public int numTrees(int n) { + // Catalan number; + int c = 1; + for (int i = 2; i <= n; i++) { + c = c * 2 * (2 * i - 1) / (i + 1); + } + return c; + } + } + + public static class UnitTest { + + } +} diff --git a/src/main/java/unique_binary_search_trees_ii/UniqueBinarySearchTreesII.java b/src/main/java/unique_binary_search_trees_ii/UniqueBinarySearchTreesII.java new file mode 100644 index 0000000..5bcc91a --- /dev/null +++ b/src/main/java/unique_binary_search_trees_ii/UniqueBinarySearchTreesII.java @@ -0,0 +1,38 @@ +package unique_binary_search_trees_ii; + +import java.util.ArrayList; + +import common.TreeNode; + +public class UniqueBinarySearchTreesII { + + public class Solution { + + private ArrayList generateTrees(int start, int end) { + ArrayList ans = new ArrayList(); + if (start > end) { + ans.add(null); + return ans; + } + for (int i = start; i <= end; i++) { + for (TreeNode left : generateTrees(start, i - 1)) { + for (TreeNode right : generateTrees(i + 1, end)) { + TreeNode p = new TreeNode(i); + p.left = left; + p.right = right; + ans.add(p); + } + } + } + return ans; + } + + public ArrayList generateTrees(int n) { + return generateTrees(1, n); + } + } + + public static class UnitTest { + + } +} diff --git a/src/main/java/unique_paths_ii/UniquePathsII.java b/src/main/java/unique_paths_ii/UniquePathsII.java index af0f200..8bde61d 100644 --- a/src/main/java/unique_paths_ii/UniquePathsII.java +++ b/src/main/java/unique_paths_ii/UniquePathsII.java @@ -4,18 +4,20 @@ public class UniquePathsII { public class Solution { public int uniquePathsWithObstacles(int[][] obstacleGrid) { - int m = obstacleGrid.length; - int n = obstacleGrid[0].length; + if (obstacleGrid.length == 0 || obstacleGrid[0].length == 0) return 0; + int m = obstacleGrid.length, n = obstacleGrid[0].length; + if (obstacleGrid[0][0] == 1) return 0; int[] dp = new int[n]; - dp[0] = obstacleGrid[0][0] == 1 ? 0 : 1; - for (int i = 0; i < m; i++) { - dp[0] = obstacleGrid[i][0] == 1 ? 0 : dp[0]; - for (int j = 1; j < n; j++) { - dp[j] = obstacleGrid[i][j] == 1 ? 0 : dp[j - 1] + dp[j]; + dp[0] = 1; + for (int i = 0; i < m; ++i) { + for (int j = 0; j < n; ++j) { + if (obstacleGrid[i][j] == 1) dp[j] = 0; + else if (j > 0) dp[j] += dp[j - 1]; //rolling array } } return dp[n - 1]; } + } public static class UnitTest { diff --git a/src/main/java/unique_word_abbrev/UniqWordAbbrev.java b/src/main/java/unique_word_abbrev/UniqWordAbbrev.java new file mode 100644 index 0000000..1febd7f --- /dev/null +++ b/src/main/java/unique_word_abbrev/UniqWordAbbrev.java @@ -0,0 +1,45 @@ +package unique_word_abbrev; + + +import java.util.*; + +/** + * Created by lxie on 6/17/18. + */ +public class UniqWordAbbrev { + + Map> m = new HashMap<>(); + + public void ValidWordAbbr(List dictionary) { + for (String a : dictionary) { + String k = a.charAt(0) + Integer.toString(a.length() - 2) + a.charAt(a.length()-1); + if (m.containsKey(k)) { + m.get(k).add(a); + } else { + m.put(k, new HashSet(Arrays.asList(a))); + } + } + } + + public boolean isUnique(String word) { + String k = word.charAt(0) + Integer.toString(word.length() - 2) + word.charAt(word.length()-1); + if (m.containsKey(k)) { + return (m.get(k).contains(word) ? 1 : 0) == m.get(k).size(); + } else { + return true; + } + } + + public static void main(String[] args) { + System.out.println("this is for test"); + List dict = new ArrayList<>(Arrays.asList("deer", "door", "cake", "card")); + UniqWordAbbrev u = new UniqWordAbbrev(); + u.ValidWordAbbr(dict); + + System.out.println(u.isUnique("dear")); + System.out.println(u.isUnique("cart")); + System.out.println(u.isUnique("cane")); + System.out.println(u.isUnique("make")); + + } +} diff --git a/src/main/java/utf8_validation/UTF8Validation.java b/src/main/java/utf8_validation/UTF8Validation.java new file mode 100644 index 0000000..caf2eda --- /dev/null +++ b/src/main/java/utf8_validation/UTF8Validation.java @@ -0,0 +1,31 @@ +package utf8_validation; + +/** + * Created by lxie on 9/20/17. + */ +public class UTF8Validation { + + class Solution { + public boolean validUtf8(int[] data) { + int cnt = 0; + for (int d : data) { + if (cnt == 0) { + if ((d >> 5) == 0b110) cnt = 1; + else if ((d >> 4) == 0b1110) cnt = 2; + else if ((d >> 3) == 0b11110) cnt = 3; + else if (d >> 7 != 0) return false; + } else { + if ((d >> 6) != 0b10) return false; + --cnt; + } + } + return cnt == 0; + + } + } + + public static void main(String[] args) { + System.out.println("this is for test"); + } + +} diff --git a/src/main/java/valid_anagram/ValidAnagram.java b/src/main/java/valid_anagram/ValidAnagram.java new file mode 100644 index 0000000..606b299 --- /dev/null +++ b/src/main/java/valid_anagram/ValidAnagram.java @@ -0,0 +1,25 @@ +package valid_anagram; + +/** + * Created by lxie on 3/6/18. + */ +public class ValidAnagram { + + public class Solution { + public boolean isAnagram(String s, String t) { + int lens = s.length(), lent = t.length(); + if (lens != lent) return false; + int[] m = new int[26]; + for (int i = 0; i < lens; ++i) ++m[s.toCharArray()[i] - 'a']; + for (int i = 0; i < lent; ++i) { + if (--m[t.toCharArray()[i] - 'a'] < 0) return false; + } + return true; + } + } + + public static class UnitTest { + + } + +} diff --git a/src/main/java/valid_number/ValidNumber.java b/src/main/java/valid_number/ValidNumber.java new file mode 100644 index 0000000..2c66950 --- /dev/null +++ b/src/main/java/valid_number/ValidNumber.java @@ -0,0 +1,103 @@ +package valid_number; + +public class ValidNumber { + + enum Status { + INIT, SYMBOL, INT, DOT, FRAC, E, SYMBOL_E, INT_E + } + + public class Solution { + + public boolean isNumber(String s) { + s = s.trim(); + Status status = Status.INIT; + boolean hasInt = false; + for (int i = 0; i < s.length(); i++) { + char c = s.charAt(i); + switch (status) { + case INIT: + if (c == '+' || c == '-') { + status = Status.SYMBOL; + } else if (Character.isDigit(c)) { + status = Status.INT; + hasInt = true; + } else if (c == '.') { + status = Status.DOT; + } else { + return false; + } + break; + case SYMBOL: + if (Character.isDigit(c)) { + status = Status.INT; + hasInt = true; + } else if (c == '.') { + status = Status.DOT; + } else { + return false; + } + break; + case INT: + if (Character.isDigit(c)) { + + } else if (c == '.') { + status = Status.DOT; + } else if (c == 'E' || c == 'e') { + status = Status.E; + } else { + return false; + } + break; + case DOT: + if (Character.isDigit(c)) { + status = Status.FRAC; + } else if (c == 'E' || c == 'e') { + if (!hasInt) { + return false; + } + status = Status.E; + } else { + return false; + } + break; + case FRAC: + if (Character.isDigit(c)) { + } else if (c == 'E' || c == 'e') { + status = Status.E; + } else { + return false; + } + break; + case E: + if (Character.isDigit(c)) { + status = Status.INT_E; + } else if (c == '+' || c == '-') { + status = Status.SYMBOL_E; + } else { + return false; + } + break; + case SYMBOL_E: + if (Character.isDigit(c)) { + status = Status.INT_E; + } else { + return false; + } + break; + case INT_E: + if (Character.isDigit(c)) { + } else { + return false; + } + break; + } + } + return (hasInt && status == Status.DOT) || status == Status.INT + || status == Status.FRAC || status == Status.INT_E; + } + } + + public static class UnitTest { + + } +} diff --git a/src/main/java/valid_palindrome_ii/ValidPalindromeII.java b/src/main/java/valid_palindrome_ii/ValidPalindromeII.java new file mode 100644 index 0000000..c99d721 --- /dev/null +++ b/src/main/java/valid_palindrome_ii/ValidPalindromeII.java @@ -0,0 +1,41 @@ +package valid_palindrome_ii; + +/** + * Created by lxie on 9/28/18. + */ +public class ValidPalindromeII { + + public class Solution { + + public boolean validPalindrome(String s) { + int left = 0, right = s.length() - 1; + while (left < right) { + if (s.charAt(left) == s.charAt(right)) { + ++left; --right; + } else { + int l = left, r = right - 1; + while (l < r) { + if (s.charAt(l) != s.charAt(r)) break; + ++l; --r; + if (l >= r) return true; + } + ++left; + while (left < right) { + if (s.charAt(left) != s.charAt(right)) return false; + ++left; --right; + } + } + } + return true; + } + + + } + + public class UnitTest { + + + } + + +} diff --git a/src/main/java/valid_sudoku/ValidSudoku.java b/src/main/java/valid_sudoku/ValidSudoku.java index 5798ccf..4271018 100644 --- a/src/main/java/valid_sudoku/ValidSudoku.java +++ b/src/main/java/valid_sudoku/ValidSudoku.java @@ -4,20 +4,21 @@ public class ValidSudoku { public class Solution { public boolean isValidSudoku(char[][] board) { - boolean[][] rows = new boolean[9][9]; - boolean[][] columns = new boolean[9][9]; - boolean[][] cells = new boolean[9][9]; - for (int i = 0; i < 9; i++) { - for (int j = 0; j < 9; j++) { + int m = board.length, n = board[0].length; + boolean[][] rows = new boolean[m][n]; + boolean[][] columns = new boolean[m][n]; + boolean[][] cells = new boolean[m][n]; + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { if (board[i][j] == '.') { continue; } - int num = board[i][j] - '1'; - if (rows[i][num] || columns[j][num] - || cells[i / 3 * 3 + j / 3][num]) { + int c = board[i][j] - '1'; + if (rows[i][c] || columns[c][j] + || cells[i / 3 * 3 + j / 3][c]) { return false; } - rows[i][num] = columns[j][num] = cells[i / 3 * 3 + j / 3][num] = true; + rows[i][c] = columns[c][j] = cells[i / 3 * 3 + j / 3][c] = true; } } return true; diff --git a/src/main/java/valid_word_abbrev/ValidWordAbbrev.java b/src/main/java/valid_word_abbrev/ValidWordAbbrev.java new file mode 100644 index 0000000..411b1db --- /dev/null +++ b/src/main/java/valid_word_abbrev/ValidWordAbbrev.java @@ -0,0 +1,32 @@ +package valid_word_abbrev; + +/** + * Created by lxie on 9/5/18. + */ +public class ValidWordAbbrev { + + public class Solution { + + public boolean validWordAbbreviation(String word, String abbr) { + int i = 0, j = 0, m = word.length(), n = abbr.length(); + while (i < m && j < n) { + if (abbr.charAt(j) >= '0' && abbr.charAt(j) <= '9') { + if (abbr.charAt(j) == '0') return false; + int val = 0; + while (j < n && abbr.charAt(j) >= '0' && abbr.charAt(j) <= '9') { + val = val * 10 + abbr.charAt(j++) - '0'; + } + i += val; + } else { + if (word.charAt(i++) != abbr.charAt(j++)) return false; + } + } + return i == m && j == n; + } + } + + public class UnitTest { + + } + +} diff --git a/src/main/java/valid_word_square/ValidWordSquare.java b/src/main/java/valid_word_square/ValidWordSquare.java new file mode 100644 index 0000000..f7ba05e --- /dev/null +++ b/src/main/java/valid_word_square/ValidWordSquare.java @@ -0,0 +1,34 @@ +package valid_word_square; + +/** + * Created by lxie on 8/19/18. + */ +public class ValidWordSquare { + + public class Solution { + public boolean validWordSquare(String[] words) { + // Write your code here + char[][] square = new char[words.length][words.length]; + + for (int i = 0; i < words.length; i++) { + square[i] = words[i].toCharArray(); + } + + for (int i = 0; i < square.length; i++) { + for (int j = 0; j <= i; j++) { + if (square[i][j] != square[j][i]) { + return false; + } + } + } + + return true; + } + + } + + public class UnitTest { + + + } +} diff --git a/src/main/java/validate_binary_search_tree/ValidateBinarySearchTree.java b/src/main/java/validate_binary_search_tree/ValidateBinarySearchTree.java index a041703..f95e977 100644 --- a/src/main/java/validate_binary_search_tree/ValidateBinarySearchTree.java +++ b/src/main/java/validate_binary_search_tree/ValidateBinarySearchTree.java @@ -5,31 +5,15 @@ public class ValidateBinarySearchTree { public class Solution { - private boolean isValidBST(TreeNode root, int[] minMax) { - int min = root.val; - int max = root.val; - if (root.left != null) { - if (!isValidBST(root.left, minMax) || root.val <= minMax[1]) { - return false; - } - min = minMax[0]; - } - if (root.right != null) { - if (!isValidBST(root.right, minMax) || root.val >= minMax[0]) { - return false; - } - max = minMax[1]; - } - minMax[0] = min; - minMax[1] = max; - return true; - } public boolean isValidBST(TreeNode root) { - if (root == null) { - return true; - } - return isValidBST(root, new int[2]); + return isValidBST(root, Long.MIN_VALUE, Long.MAX_VALUE); + } + + private boolean isValidBST(TreeNode root, long mn, long mx) { + if (root == null) return true; + if (root.val <= mn || root.val >= mx) return false; + return isValidBST(root.left, mn, root.val) && isValidBST(root.right, root.val, mx); } } diff --git a/src/main/java/verify_preorder_btree/VerifyPreorderBTree.java b/src/main/java/verify_preorder_btree/VerifyPreorderBTree.java new file mode 100644 index 0000000..27ef296 --- /dev/null +++ b/src/main/java/verify_preorder_btree/VerifyPreorderBTree.java @@ -0,0 +1,28 @@ +package verify_preorder_btree; + +/** + * Created by lxie on 11/26/17. + */ +public class VerifyPreorderBTree { + public class Solution { + public boolean isPreorderBTree(String preorder) { + if (preorder.isEmpty()) return false; + String[] v = preorder.split(","); + int d = 0; + for (int i = 0; i < v.length - 1; ++i) { + if (v[i] == "#") { + if (d == 0) return false; + else --d; + } + else ++d; + } + return d != 0 ? false : v[v.length - 1] == "#"; + } + + } + + public static class UnitTest { + + } + +} diff --git a/src/main/java/verify_preorder_sequence_bst/PreorderSeqBst.java b/src/main/java/verify_preorder_sequence_bst/PreorderSeqBst.java new file mode 100644 index 0000000..42940b3 --- /dev/null +++ b/src/main/java/verify_preorder_sequence_bst/PreorderSeqBst.java @@ -0,0 +1,52 @@ +package verify_preorder_sequence_bst; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Stack; + +/** + * Created by lxie on 5/28/18. + */ +public class PreorderSeqBst { + + public static class Solution { + + public boolean verifyPreorder(List preorder) { + int low = Integer.MIN_VALUE; + Stack s = new Stack<>(); + for (int a : preorder) { + if (a < low) return false; + while (!s.empty() && a > s.peek()) { + low = s.peek(); s.pop(); + } + s.push(a); + } + return true; + } + + + public boolean verifyPreorderRecursive(List preorder) { + return helper(preorder, 0, preorder.size() - 1, Integer.MIN_VALUE, Integer.MAX_VALUE); + } + + boolean helper(List preorder, int start, int end, int lower, int upper) { + if (start > end) return true; + int val = preorder.get(start), i = 0; + if (val <= lower || val >= upper) return false; + for (i = start + 1; i <= end; ++i) { + if (preorder.get(i) >= val) break; + } + return helper(preorder, start + 1, i - 1, lower, val) && helper(preorder, i, end, val, upper); + } + + } + + public static void main(String[] args) { + Solution sol = new Solution(); + boolean res = sol.verifyPreorderRecursive(new ArrayList(Arrays.asList(5, 2, 1, 3, 6, 8, 7))); + System.out.println("result is " + res); + } + + +} diff --git a/src/main/java/walls_and_gates/WallAndGates.java b/src/main/java/walls_and_gates/WallAndGates.java new file mode 100644 index 0000000..6c186a7 --- /dev/null +++ b/src/main/java/walls_and_gates/WallAndGates.java @@ -0,0 +1,39 @@ +package walls_and_gates; + +/** + * Created by lxie on 6/16/18. + */ +public class WallAndGates { + + public class Solution { + + public void wallsAndGates(int[][] rooms) { + for (int i = 0; i < rooms.length; ++i) { + for (int j = 0; j < rooms[i].length; ++j) { + if (rooms[i][j] == 0) { + dfs(rooms, i + 1, j, 1); + dfs(rooms, i - 1, j, 1); + dfs(rooms, i, j + 1, 1); + dfs(rooms, i, j - 1, 1); + } + } + } + } + + private void dfs(int[][] rooms, int i, int j, int val) { + if (i < 0 || i >= rooms.length || j < 0 || j >= rooms[i].length) return; + if (rooms[i][j] > val) { + rooms[i][j] = val; + dfs(rooms, i + 1, j, val + 1); + dfs(rooms, i - 1, j, val + 1); + dfs(rooms, i, j + 1, val + 1); + dfs(rooms, i, j - 1, val + 1); + } + } + + } + + public class UnitTest { + + } +} diff --git a/src/main/java/ways_to_add_parentheses/DiffWaysAddParentheses.java b/src/main/java/ways_to_add_parentheses/DiffWaysAddParentheses.java new file mode 100644 index 0000000..cf401f6 --- /dev/null +++ b/src/main/java/ways_to_add_parentheses/DiffWaysAddParentheses.java @@ -0,0 +1,36 @@ +package ways_to_add_parentheses; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by lxie on 12/11/17. + */ +public class DiffWaysAddParentheses { + public class Solution { + public List diffWaysToCompute(String input) { + List res = new ArrayList<>(); + char[] input1 = input.toCharArray(); + for (int i = 0; i < input.length(); ++i) { + if (input1[i] == '+' || input1[i] == '-' || input1[i] == '*') { + List left = diffWaysToCompute(input.substring(0, i)); + List right = diffWaysToCompute(input.substring(i + 1)); + for (int j = 0; j < left.size(); ++j) { + for (int k = 0; k < right.size(); ++k) { + if (input1[i] == '+') res.add(left.get(j) + right.get(k)); + else if (input1[i] == '-') res.add(left.get(j) - right.get(k)); + else res.add(left.get(j) * right.get(k)); + } + } + } + } + if (res.isEmpty()) res.add(Integer.parseInt(input)); // input is an integer + return res; + } + } + + public static class UnitTest { + + } + +} diff --git a/src/main/java/wiggle_sort/WiggleSort.java b/src/main/java/wiggle_sort/WiggleSort.java new file mode 100644 index 0000000..f19138f --- /dev/null +++ b/src/main/java/wiggle_sort/WiggleSort.java @@ -0,0 +1,24 @@ +package wiggle_sort; + +/** + * Created by lxie on 1/8/18. + */ +public class WiggleSort { + + public void wiggleSort(int[] nums) { + // Write your code here + for(int i=1; i nums[i-1]))) { + swap(nums, i-1, i); + } + } + } + + public void swap(int[] nums, int i, int j) { + int temp = nums[i]; + nums[i] = nums[j]; + nums[j] = temp; + } + +} diff --git a/src/main/java/wiggle_sort_II/WiggleSortII.java b/src/main/java/wiggle_sort_II/WiggleSortII.java new file mode 100644 index 0000000..7eef9df --- /dev/null +++ b/src/main/java/wiggle_sort_II/WiggleSortII.java @@ -0,0 +1,27 @@ +package wiggle_sort_II; + +import java.util.Arrays; + +/** + * Created by lxie on 1/8/18. + */ +public class WiggleSortII { + + public static void wiggleSort(int[] nums) { + int[] tmp = Arrays.copyOf(nums, nums.length) ; + int n = nums.length, k = (n + 1) / 2, j = n; + Arrays.sort(tmp); + for (int i = 0; i < n; ++i) { + nums[i] = (i & 1) != 0 ? tmp[--j] : tmp[--k]; + } + } + + public static void main(String[] args) { + int[] nums = {1, 5, 1, 1, 6, 4}; + wiggleSort(nums); + for (int i : nums) { + System.out.print(i + ", "); + } + + } +} diff --git a/src/main/java/wiggle_subsequence/WiggleSubsequence.java b/src/main/java/wiggle_subsequence/WiggleSubsequence.java new file mode 100644 index 0000000..032b62c --- /dev/null +++ b/src/main/java/wiggle_subsequence/WiggleSubsequence.java @@ -0,0 +1,36 @@ +package wiggle_subsequence; + +/** + * Created by lxie on 11/2/17. + */ +public class WiggleSubsequence { + + public class Solution { + + public int wiggleMaxLength(int[] nums) { + int n = nums.length; + if (n == 0) return 0; + + + int[] p = new int[n]; + int[] q = new int[n]; + for (int i = 0; i < n; ++i) { + p[i] = q[i] = 1; + } + + for (int i = 1; i < n; ++i) { + for (int j = 0; j < i; ++j) { + if (nums[i] > nums[j]) p[i] = Math.max(p[i], q[j] + 1); + else if (nums[i] < nums[j]) q[i] = Math.max(q[i], p[j] + 1); + } + } + return Math.max(p[n-1], q[n-1]); + } + } + + public static class UnitTest { + + } + + +} diff --git a/src/main/java/wildcard_matching/WildcardMatching.java b/src/main/java/wildcard_matching/WildcardMatching.java new file mode 100644 index 0000000..67ae1e5 --- /dev/null +++ b/src/main/java/wildcard_matching/WildcardMatching.java @@ -0,0 +1,30 @@ +package wildcard_matching; + +public class WildcardMatching { + + public class Solution { + + public boolean isMatch(String s, String p) { + int m = s.length(), n = p.length(); + boolean[][] dp = new boolean[m+1][n+1]; + dp[0][0] = true; + for (int i = 1; i <= n; ++i) { + if (p.charAt(i-1) == '*') dp[0][i] = dp[0][i - 1]; + } + for (int i = 1; i <= m; ++i) { + for (int j = 1; j <= n; ++j) { + if (p.charAt(j-1) == '*') { + dp[i][j] = dp[i - 1][j] || dp[i][j - 1]; + } else { + dp[i][j] = (s.charAt(i-1) == p.charAt(j-1) || p.charAt(j-1) == '?') && dp[i - 1][j - 1]; + } + } + } + return dp[m][n]; + } + + } + + public static class UnitTest { + } +} diff --git a/src/main/java/word_abbreviation/WordAbbreviation.java b/src/main/java/word_abbreviation/WordAbbreviation.java new file mode 100644 index 0000000..1c9a68e --- /dev/null +++ b/src/main/java/word_abbreviation/WordAbbreviation.java @@ -0,0 +1,46 @@ +package word_abbreviation; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +/** + * Created by lxie on 9/18/18. + */ +public class WordAbbreviation { + + public String[] wordsAbbreviation(String[] dict) { + int n = dict.length; + String[] res = new String[n]; + int[] pre = new int[n]; Arrays.fill(pre, 1); + for (int i = 0; i < n; ++i) { + res[i] = abbreviate(dict[i], pre[i]); + } + for (int i = 0; i < n; ++i) { + while (true) { + Set s = new HashSet<>(); + for (int j = i + 1; j < n; ++j) { + if (res[j].equals(res[i])) s.add(j); + } + if (s.isEmpty()) break; + s.add(i); + for (int a : s) { + res[a] = abbreviate(dict[a], ++pre[a]); + } + } + } + return res; + } + + private String abbreviate(String s, int k) { + return (k >= s.length() - 2) ? s : s.substring(0, k) + Integer.toString(s.length() - k - 1) + + s.charAt(s.length()-1); + } + + + public static void main(String[] args) { + WordAbbreviation w = new WordAbbreviation(); + String[] dict = {"like", "god", "internal", "me", "internet", "interval", "intension", "face", "intrusion"}; + System.out.println(Arrays.toString(w.wordsAbbreviation(dict))); + } +} diff --git a/src/main/java/word_break_ii/WordBreakII.java b/src/main/java/word_break_ii/WordBreakII.java index 691398c..5f23e3c 100644 --- a/src/main/java/word_break_ii/WordBreakII.java +++ b/src/main/java/word_break_ii/WordBreakII.java @@ -1,43 +1,55 @@ package word_break_ii; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Map; -import java.util.Set; +import java.util.*; public class WordBreakII { - public class Solution { - private ArrayList searchWordBreak(String s, Set dict, - Map> solutions) { - ArrayList solution = solutions.get(s); - if (solution != null) { - return solution; + public static class Solution { + public ArrayList wordBreak(String s, Set dict) { + Map> memo = new HashMap>(); + return wordBreakHelper(s, dict, memo); + } + + public ArrayList wordBreakHelper(String s, + Set dict, + Map> memo){ + if (memo.containsKey(s)) { + return memo.get(s); } - solution = new ArrayList(); - for (int i = 1; i < s.length(); i++) { - String prefix = s.substring(0, i); - if (dict.contains(prefix)) { - for (String subfix : searchWordBreak(s.substring(i), dict, - solutions)) { - solution.add(prefix + " " + subfix); - } - } + + ArrayList results = new ArrayList(); + + if (s.length() == 0) { + return results; } + if (dict.contains(s)) { - solution.add(s); + results.add(s); } - solutions.put(s, solution); - return solution; - } - public ArrayList wordBreak(String s, Set dict) { - return searchWordBreak(s, dict, - new HashMap>()); + for (int len = 1; len < s.length(); ++len){ + String word = s.substring(0, len); + if (!dict.contains(word)) { + continue; + } + + String suffix = s.substring(len); + ArrayList segmentations = wordBreakHelper(suffix, dict, memo); + + for (String segmentation: segmentations){ + results.add(word + " " + segmentation); + } + } + + memo.put(s, results); + return results; } } - public static class UnitTest { + public static void main(String[] args) { + Set dict = new HashSet<>(Arrays.asList("cat", "cats", "and", "sand", "dog")); + Solution sol = new Solution(); + System.out.println(sol.wordBreak("catsanddog", dict)); } } diff --git a/src/main/java/word_ladder/WordLadder.java b/src/main/java/word_ladder/WordLadder.java index 8f61281..0a8ec12 100644 --- a/src/main/java/word_ladder/WordLadder.java +++ b/src/main/java/word_ladder/WordLadder.java @@ -1,57 +1,44 @@ package word_ladder; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashSet; -import java.util.List; -import java.util.Set; +import java.util.*; public class WordLadder { - public class Solution { - public int ladderLength(String start, String end, HashSet dict) { - if (start.equals(end)) { - return 1; - } - List queue = new ArrayList(); - int level = 1; - queue.add(start); - int begin = 0; - char[] endCharArray = end.toCharArray(); - Set used = new HashSet(); - used.add(start); - while (begin < queue.size()) { - int tail = queue.size(); - for (int i = begin; i < tail; i++) { - char[] word = queue.get(i).toCharArray(); - for (int j = 0; j < word.length; j++) { - char currentChar = word[j]; - for (char c = 'a'; c <= 'z'; c++) { - if (c == currentChar) { - continue; - } - word[j] = c; - if (Arrays.equals(word, endCharArray)) { - return level + 1; - } - String nextWord = new String(word); - if (dict.contains(nextWord) - && !used.contains(nextWord)) { - used.add(nextWord); - queue.add(nextWord); - } - word[j] = currentChar; + public static class Solution { + public int ladderLength(String beginWord, String endWord, List wordList) { + if (!wordList.contains(endWord)) return 0; + Map m = new HashMap<>(); + Queue q = new LinkedList<>(); + m.put(beginWord, 1); + q.add(beginWord); + while (!q.isEmpty()) { + String word = q.remove(); + for (int i = 0; i < word.length(); ++i) { + String newWord = word; + for (char ch = 'a'; ch <= 'z'; ++ch) { + if (newWord.charAt(i) == ch) continue; + newWord = newWord.substring(0, i) + ch + newWord.substring(i + 1); + if (newWord.compareTo(endWord) == 0) return m.get(word) + 1; + if (wordList.contains(newWord) && !m.containsKey(newWord)) { + q.add(newWord); + m.put(newWord, m.get(word) + 1); } } } - level++; - begin = tail; } return 0; } + } - public static class UnitTest { + public static void main(String[] args) { + Solution sol = new Solution(); + List dict = new ArrayList( + Arrays.asList("hot","dot","dog","lot","log", "cog")); + int ret = sol.ladderLength("hit", "cog", dict); + System.out.println("test result is " + ret); } + + } diff --git a/src/main/java/word_ladder_ii/WordLadderII.java b/src/main/java/word_ladder_ii/WordLadderII.java new file mode 100644 index 0000000..bb8f3b4 --- /dev/null +++ b/src/main/java/word_ladder_ii/WordLadderII.java @@ -0,0 +1,59 @@ +package word_ladder_ii; + +import java.util.*; + +public class WordLadderII { + + public static class Solution { + + public List> findLadders(String beginWord, String endWord, List wordList) { + List> res = new ArrayList<>(new ArrayList<>()); + Set dict = new HashSet<>(wordList); + List p = new ArrayList<>(Arrays.asList(beginWord)); + Queue> paths = new LinkedList<>(); + paths.add(p); + int level = 1, minLevel = Integer.MAX_VALUE; + Set words = new HashSet<>(); + while (!paths.isEmpty()) { + List t = paths.remove(); + if (t.size() > level) { // enters a new level + for (String w : words) dict.remove(w); // removes words used in the last level + words.clear(); + level = t.size(); + if (level > minLevel) + break; + } + String last = t.get(t.size() - 1); + for (int i = 0; i < last.length(); ++i) { + // String newLast = last; + for (char ch = 'a'; ch <= 'z'; ++ch) { + if (last.charAt(i) == ch) continue; + String newLast = last.substring(0, i) + ch + last.substring(i + 1); + if (!dict.contains(newLast)) continue; + words.add(newLast); + List nextPath = new ArrayList<>(t); + nextPath.add(newLast); + if (newLast.compareTo(endWord) == 0) { + res.add(nextPath); + minLevel = level; + } else { + paths.add(nextPath); + } + + } + } + } + return res; + } + } + + public static void main(String[] args) { + Solution sol = new Solution(); + List dict = new ArrayList( + Arrays.asList("hot","dot","dog","lot","log", "cog")); + List> ret = sol.findLadders("hit", "cog", dict); + System.out.println("test result is " + ret.toString()); + + } + +} diff --git a/src/main/java/word_pattern/WordPattern.java b/src/main/java/word_pattern/WordPattern.java new file mode 100644 index 0000000..25a6ed2 --- /dev/null +++ b/src/main/java/word_pattern/WordPattern.java @@ -0,0 +1,41 @@ +package word_pattern; + +import java.util.HashMap; +import java.util.Map; + +/** + * Created by lxie on 6/18/18. + */ +public class WordPattern { + + public static class Solution { + + public boolean wordPattern(String pattern, String str) { + Map m1 = new HashMap<>(); + Map m2 = new HashMap<>(); + + String[] words = str.split(" "); + int i = 0; + if (pattern.length() != words.length) return false; + for (String word : words) { + if (!m1.containsKey(pattern.charAt(i)) && !m2.containsKey(word)) { + m1.put(pattern.charAt(i), i); + m2.put(word, i); + } else if (m1.containsKey(pattern.charAt(i)) && m2.containsKey(word)) { + if (m1.get(pattern.charAt(i)).intValue() != m2.get(word).intValue()) + return false; + } else { + return false; + } + ++i; + } + return i == pattern.length(); + } + + public static void main(String[] args) { + System.out.println("this is for test"); + Solution sol = new Solution(); + System.out.println(sol.wordPattern("abba", "dog cat cat fish")); + } + } +} diff --git a/src/main/java/word_pattern_ii/WordPatternII.java b/src/main/java/word_pattern_ii/WordPatternII.java new file mode 100644 index 0000000..ef37180 --- /dev/null +++ b/src/main/java/word_pattern_ii/WordPatternII.java @@ -0,0 +1,55 @@ +package word_pattern_ii; + +import java.util.HashMap; +import java.util.Map; + +/** + * Created by lxie on 6/19/18. + */ +public class WordPatternII { + + public static class Solution{ + + public boolean wordPatternMatch(String pattern, String str) { + Map m = new HashMap<>(); + return helper(pattern, 0, str, 0, m); + } + + private boolean helper(String pattern, int p, String str, int r, Map m) { + if (p == pattern.length() && r == str.length()) return true; + if (p == pattern.length() || r == str.length()) return false; + char c = pattern.charAt(p); + for (int i = r; i < str.length(); ++i) { + String t = str.substring(r, i+1); + if (m.containsKey(c) && m.get(c).equals(t)) { + if (helper(pattern, p + 1, str, i + 1, m)) return true; + } else if (!m.containsKey(c)) { + boolean b = false; + for (Map.Entry it : m.entrySet()) { + if (it.getValue().equals(t)) b = true; + } + if (!b) { + m.put(c, t); + if (helper(pattern, p + 1, str, i + 1, m)) return true; + m.remove(c); // backtracking + } + } + } + return false; + } + } + + public static void main(String[] args) { + System.out.println("this is for test"); + Solution sol = new Solution(); + + //pattern = "abab", str = "redblueredblue" should return true. + //pattern = "aaaa", str = "asdasdasdasd" should return true. + //pattern = "aabb", str = "xyzabcxzyabc" should return false. + System.out.println(sol.wordPatternMatch("abab", "redblueredblue")); + System.out.println(sol.wordPatternMatch("aaaa", "asdasdasdasd")); + System.out.println(sol.wordPatternMatch("aabb", "xyzabcxzyabc")); + + } + +} diff --git a/src/main/java/word_search/WordSearch.java b/src/main/java/word_search/WordSearch.java new file mode 100644 index 0000000..72dd5b3 --- /dev/null +++ b/src/main/java/word_search/WordSearch.java @@ -0,0 +1,42 @@ +package word_search; + +public class WordSearch { + + public class Solution { + private boolean search(char[][] board, int i, int j, String word, + int begin) { + if (begin == word.length()) { + return true; + } + if (i < 0 || i >= board.length || j < 0 || j >= board[0].length) { + return false; + } + if (board[i][j] == '*' || board[i][j] != word.charAt(begin)) { + return false; + } + char c = board[i][j]; + board[i][j] = '*'; + boolean re = search(board, i + 1, j, word, begin + 1) + || search(board, i - 1, j, word, begin + 1) + || search(board, i, j + 1, word, begin + 1) + || search(board, i, j - 1, word, begin + 1); + board[i][j] = c; + return re; + } + + public boolean exist(char[][] board, String word) { + for (int i = 0; i < board.length; i++) { + for (int j = 0; j < board[0].length; j++) { + if (search(board, i, j, word, 0)) { + return true; + } + } + } + return false; + } + } + + public static class UnitTest { + + } +} diff --git a/src/main/java/word_search_ii/WordSearchII.java b/src/main/java/word_search_ii/WordSearchII.java new file mode 100644 index 0000000..27a3588 --- /dev/null +++ b/src/main/java/word_search_ii/WordSearchII.java @@ -0,0 +1,80 @@ +package word_search_ii; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by lxie on 2/7/18. + */ +public class WordSearchII { + + public class Solution { + + public class TrieNode { + public TrieNode[] child = new TrieNode[26]; + public String str; + + public TrieNode() { + for (TrieNode a : child) a = null; + str = ""; + } + } + + public class Trie { + public TrieNode root; + + public Trie() { + root = new TrieNode(); + } + + public void insert(String s) { + TrieNode p = root; + for (char a : s.toCharArray()) { + int i = a - 'a'; + if (p.child[i] == null) p.child[i] = new TrieNode(); + p = p.child[i]; + } + p.str = s; + } + } + + public List findWords(char[][] board, String[] words) { + List res = new ArrayList<>(); + if (words.length == 0 || board.length == 0 || board[0].length == 0) return res; + boolean[][] visit = new boolean[board.length][board[0].length]; + + Trie T = new Trie(); + for (String a : words) T.insert(a); + for (int i = 0; i < board.length; ++i) { + for (int j = 0; j < board[i].length; ++j) { + if (T.root.child[board[i][j] - 'a'] != null) { + search(board, T.root.child[board[i][j] - 'a'], i, j, visit, res); + } + } + } + return res; + } + + private void search(char[][] board, TrieNode p, int i, int j, boolean[][] visit, List res) { + if (!p.str.isEmpty()) { + res.add(p.str); + p.str = ""; + } + int[][] d = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}}; + visit[i][j] = true; + for (int[] a : d) { + int nx = a[0] + i, ny = a[1] + j; + if (nx >= 0 && nx < board.length && ny >= 0 && ny < board[0].length + && !visit[nx][ny] && p.child[board[nx][ny] - 'a'] != null) { + search(board, p.child[board[nx][ny] - 'a'], nx, ny, visit, res); + } + } + visit[i][j] = false; + } + } + + public class UnitTest { + + } + +} diff --git a/src/main/java/word_squares/WordSquares.java b/src/main/java/word_squares/WordSquares.java new file mode 100644 index 0000000..be7c4ef --- /dev/null +++ b/src/main/java/word_squares/WordSquares.java @@ -0,0 +1,97 @@ +package word_squares; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by lxie on 8/19/18. + */ +public class WordSquares { + + public class Solution { + class TrieNode { + List startWith; + TrieNode[] children; + + TrieNode() { + startWith = new ArrayList<>(); + children = new TrieNode[26]; + } + } + + class Trie { + TrieNode root; + + Trie(String[] words) { + root = new TrieNode(); + for (String w : words) { + TrieNode cur = root; + for (char ch : w.toCharArray()) { + int idx = ch - 'a'; + if (cur.children[idx] == null) + cur.children[idx] = new TrieNode(); + cur.children[idx].startWith.add(w); + cur = cur.children[idx]; + } + } + } + + List findByPrefix(String prefix) { + List ans = new ArrayList<>(); + TrieNode cur = root; + for (char ch : prefix.toCharArray()) { + int idx = ch - 'a'; + if (cur.children[idx] == null) + return ans; + + cur = cur.children[idx]; + } + ans.addAll(cur.startWith); + return ans; + } + } + + public List> wordSquares(String[] words) { + List> ans = new ArrayList<>(); + if (words == null || words.length == 0) + return ans; + int len = words[0].length(); + Trie trie = new Trie(words); + List ansBuilder = new ArrayList<>(); + for (String w : words) { + ansBuilder.add(w); + search(len, trie, ans, ansBuilder); + ansBuilder.remove(ansBuilder.size() - 1); + } + + return ans; + } + + private void search(int len, Trie tr, List> ans, + List ansBuilder) { + if (ansBuilder.size() == len) { + ans.add(new ArrayList<>(ansBuilder)); + return; + } + + int idx = ansBuilder.size(); + StringBuilder prefixBuilder = new StringBuilder(); + for (String s : ansBuilder) + prefixBuilder.append(s.charAt(idx)); + List startWith = tr.findByPrefix(prefixBuilder.toString()); + for (String sw : startWith) { + ansBuilder.add(sw); + search(len, tr, ans, ansBuilder); + ansBuilder.remove(ansBuilder.size() - 1); + } + } + } + + + public class UnitTest { + + + + } + +} diff --git a/src/main/java/zero_one_matrix/ZeroOneMatrix.java b/src/main/java/zero_one_matrix/ZeroOneMatrix.java new file mode 100644 index 0000000..040d90a --- /dev/null +++ b/src/main/java/zero_one_matrix/ZeroOneMatrix.java @@ -0,0 +1,44 @@ +package zero_one_matrix; + +import java.util.LinkedList; +import java.util.Queue; + +/** + * Created by lxie on 9/3/18. + */ +public class ZeroOneMatrix { + + public class Solution { + + public int[][] updateMatrix(int[][] matrix) { + int m = matrix.length, n = matrix[0].length; + int[][] dirs = {{0,-1},{-1,0},{0,1},{1,0}}; + Queue q = new LinkedList<>(); + for (int i = 0; i < m; ++i) { + for (int j = 0; j < n; ++j) { + if (matrix[i][j] == 0) q.add(new int[]{i, j}); + else matrix[i][j] = Integer.MAX_VALUE; + } + } + while (!q.isEmpty()) { + int[] t = q.peek(); q.poll(); + for (int[] dir : dirs) { + int x = t[0] + dir[0], y = t[1] + dir[1]; + if (x < 0 || x >= m || y < 0 || y >= n || + matrix[x][y] <= matrix[t[0]][t[1]]) continue; + matrix[x][y] = matrix[t[0]][t[1]] + 1; + q.add(new int[]{x, y}); + } + } + return matrix; + } + } + + public class UnitTest { + + + + } + + +} diff --git a/src/main/java/zigzag_iterator/ZigzagIterator.java b/src/main/java/zigzag_iterator/ZigzagIterator.java new file mode 100644 index 0000000..b58251f --- /dev/null +++ b/src/main/java/zigzag_iterator/ZigzagIterator.java @@ -0,0 +1,30 @@ +package zigzag_iterator; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by lxie on 6/15/18. + */ +public class ZigzagIterator { + + private List v = new ArrayList<>(); + public int i = 0; + + public ZigzagIterator(List v1, List v2) { + int n1 = v1.size(), n2 = v2.size(), n = Math.max(n1, n2); + for (int i = 0; i < n; ++i) { + if (i < n1) v.add(v1.get(i)); + if (i < n2) v.add(v2.get(i)); + } + } + + public int next() { + return v.get(i++); + } + + public boolean hasNext() { + return i < v.size(); + } + +}