diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..816a796
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+GenerateCodeTable.class
diff --git a/GenerateCodeTable.class b/GenerateCodeTable.class
deleted file mode 100644
index da90633..0000000
Binary files a/GenerateCodeTable.class and /dev/null differ
diff --git a/GenerateCodeTable.java b/GenerateCodeTable.java
index d89f687..abfd985 100644
--- a/GenerateCodeTable.java
+++ b/GenerateCodeTable.java
@@ -1,113 +1,211 @@
-import java.io.*;
-/*
-Used to generate table of contents.
-1. No args: generate GitHub table
-2. args == 'word', generate WordPress table.
-3. args == 'all', genereate both table
-*/
-public class GenerateCodeTable {
- public static void main(String[] args) {
- //Read Java Solution Folder
- File folder = new File("./Java");//"." = current path
- if (!folder.exists() || !folder.isDirectory()) {
- System.out.println("Check Directory:1");
- return;
- }
- File[] listOfFiles = folder.listFiles();
- if (listOfFiles == null) {
- System.out.println("Check Directory:2");
- return;
- }
-
- String outputContent = "";
- File outFile;
-
- if (args.length == 0){
- outputContent = generateREADME(listOfFiles);
- printTable("README.md", outputContent);
- } else if (args != null && args[0].contains("word")) {//Wordpress
- outputContent = generateWordPressPage(listOfFiles);
- printTable("WordPress.txt", outputContent);
- } else if (args != null && args[0].contains("all")) {
- outputContent = generateREADME(listOfFiles);
- printTable("README.md", outputContent);
- outputContent = generateWordPressPage(listOfFiles);
- printTable("WordPress.txt", outputContent);
- } else {
- return;
- }
-
-
- }
-
- public static String generateWordPressPage(File[] listOfFiles) {
- //Assemble output
- String outputContent = "Java Solutions to problems from LintCode(http://LintCode.com).\n" +
- "
" +
- "" +
- "" +
- "| # | " +
- "Problem | " +
- " Level | " +
- " Language | " +
- "
" +
- "" +
- "";
-
- int count = 0;
- for (File file : listOfFiles) {
- if (file.getName().contains(".java")) {
- //outputContent += "|" + count + "|[" + file.getName() + "](https://github.com/shawnfan/LintCode/blob/master/Java/"+ file.getName() +")| |" + "Java|\n";
- outputContent+=
- "" +
- "| " + count + " | " +
- "" + file.getName() + " | " +
- " | " +
- "Java | " +
- "
";
- count++;
- }
- }
-
- outputContent += "
";
- return outputContent;
- }
-
-
- /*
- Generate GitHub ReadMe file
- */
- public static String generateREADME(File[] listOfFiles) {
- //Assemble output
- String outputContent = "# LintCode\n\n" +
- "To host Java Solutions to problems from LintCode(http://LintCode.com).\n" +
- "I Will try to revise the solutions once new problem or new testing case occurs.\n\n" +
- "| Squence | Problem | Level | Language |\n" +
- "|:-------:|:--------------|:---------------|:---------:|\n";
- int count = 0;
- for (File file : listOfFiles) {
- if (file.getName().contains(".java")) {
- outputContent += "|" + count + "|[" + file.getName() + "](https://github.com/shawnfan/LintCode/blob/master/Java/"+ file.getName() +")| |" + "Java|\n";
- count++;
- }
- }
- return outputContent;
- }
-
- public static void printTable(String fileName, String outputContent) {
- System.out.println(outputContent);
- //Write to README.md
- try {
- File outFile = new File(fileName);
- FileOutputStream fop = new FileOutputStream(outFile);
- byte[] contentInBytes = outputContent.getBytes();
- fop.write(contentInBytes);
- fop.flush();
- fop.close();
- System.out.println("Mission Accomplished. Now go ahead and commit");
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
-
+import java.io.*;
+/*
+Used to generate table of contents.
+ - No args: generate GitHub table
+ - args == 'wordpress', generate WordPress table.
+ - args == 'review', generate Review Page
+ - args == 'all', genereate both table
+*/
+public class GenerateCodeTable {
+ public final static String TUTORIAL_KEY_WORD = "tutorial:";
+ public static void main(String[] args) {
+ //Read Java Solution Folder
+ File folder = new File("./Java");//"." = current path
+ if (!folder.exists() || !folder.isDirectory()) {
+ System.out.println("Check Directory:1");
+ return;
+ }
+ File[] listOfFiles = folder.listFiles();
+ if (listOfFiles == null) {
+ System.out.println("Check Directory:2");
+ return;
+ }
+
+ String outputContent = "";
+ File outFile;
+
+ if (args.length == 0){
+ outputContent = generateREADME(listOfFiles);
+ printTable("README.md", outputContent);
+ } else if (args != null && args[0].contains("wordpress")) {//Wordpress
+ outputContent = generateWordPressPage(listOfFiles);
+ printTable("WordPress.txt", outputContent);
+ } else if (args != null && args[0].contains("review")) {//Review Page
+ outputContent = generateReviewPage(listOfFiles);
+ printTable("ReviewPage.md", outputContent);
+ } else if (args != null && args[0].contains("all")) {
+ outputContent = generateREADME(listOfFiles);
+ printTable("README.md", outputContent);
+ outputContent = generateWordPressPage(listOfFiles);
+ printTable("WordPress.txt", outputContent);
+ outputContent = generateReviewPage(listOfFiles);
+ printTable("ReviewPage.md", outputContent);
+ } else {
+ return;
+ }
+ }
+
+ /*
+ Output the content into file
+ */
+ public static void printTable(String fileName, String outputContent) {
+ System.out.println(outputContent);
+ //Write to README.md
+ try {
+ File outFile = new File(fileName);
+ FileOutputStream fop = new FileOutputStream(outFile);
+ byte[] contentInBytes = outputContent.getBytes();
+ fop.write(contentInBytes);
+ fop.flush();
+ fop.close();
+ System.out.println("Mission Accomplished. Now go ahead and commit");
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /*
+ Generate Wordpress contents
+ */
+ public static String generateWordPressPage(File[] listOfFiles) {
+ //Assemble output
+ String outputContent = "Java Solutions to algorithm problems from LintCode, LeetCode...etc.\n" +
+ "" +
+ "" +
+ "" +
+ "| # | " +
+ "Problem | " +
+ " Level | " +
+ " Language | " +
+ "
" +
+ "" +
+ "";
+
+ int count = 0;
+ for (File file : listOfFiles) {
+ if (file.getName().contains(".java")) {
+ //outputContent += "|" + count + "|[" + file.getName() + "](https://github.com/awangdev/LintCode/blob/master/Java/"+ file.getName() +")| |" + "Java|\n";
+ outputContent+=
+ "" +
+ "| " + count + " | " +
+ "" + file.getName() + " | " +
+ " | " +
+ "Java | " +
+ "
";
+ count++;
+ }
+ }
+
+ outputContent += "
";
+ return outputContent;
+ }
+
+
+ /*
+ Generate GitHub ReadMe contents
+ */
+ public static String generateREADME(File[] listOfFiles) {
+ //Assemble output
+ String outputContent = "# Java Algorithm Problems\n\n" +
+ "### 前戏\n" +
+ "To host Java Solutions to algorithm problems from LintCode, LeetCode...etc.\n" +
+ "I Will try to revise the solutions once new problem or new testing case occurs.\n" +
+ "**Mid 2016** I realize that people may want to contribute to this repo, and make it better by contributing fixes, better solutions ... etc. Free free to send pull request. Once verified, I'm happy to merge in!\n" +
+ "CALM DOWN AND CODE ON! Fellows! \n\n" +
+ "### News\n" +
+ "2017年1月17日, 陪我征战多年的 2014 MackBookPro i7 3.xGHz 被一杯清水结束了生命,在这里深切缅怀悼念。这个Git Repo是小M陪我一字一句打出来的,有过蹉跎,也有过辉煌,陪我从Day1刷题一直刷到了Day1之中。直至今日,小M记录的代码还在给广大coder带来福利。为了延续小M无私奉献的精神,我将重新在这个repo活跃起来,重整已有的问题,也会尝试总结一些System Design方面的想法,将小M还没有能够达成的梦想实现。\n\n" +
+ "| Squence | Problem | Level | Language | Video Tutorial|\n" +
+ "|:-------:|:--------------|:------:|:---------:|:-------------:|\n";
+ int count = 0;
+ for (File file : listOfFiles) {
+ String tutorialLink = "";
+ String calculatedLevel = "";
+ if (file.getName().contains(".java")) {
+ try {
+ final BufferedReader reader = new BufferedReader(new InputStreamReader(
+ new FileInputStream("Java/" + file.getName()), "UTF-8"));
+ final String levelLine = reader.readLine().trim();
+ if (levelLine.length() == 1) {
+ calculatedLevel = calculateLevel(levelLine.toUpperCase());
+ }
+ final String tutorialLine = reader.readLine();
+ if (tutorialLine.indexOf(TUTORIAL_KEY_WORD) == 0) {
+ tutorialLink = "[Link](" + tutorialLine.substring(TUTORIAL_KEY_WORD.length()) + ")";
+ }
+ } catch (Exception e) {
+ System.err.format("IOException: %s%n", e);
+ }
+ String convertedFileName = file.getName().replace(" ", "%20");
+ outputContent += "|" + count + "|[" + file.getName() + "](https://github.com/awangdev/LintCode/blob/master/Java/"
+ + convertedFileName + ")|" + calculatedLevel + "|" + "Java|" + tutorialLink + "|\n";
+ count++;
+ }
+ }
+ return outputContent;
+ }
+
+
+ /*
+ Generate Review Page contents
+ Review Page content:
+ 1. Sequence
+ 2. Name
+ 3. Difficulty
+ 4. Summary of solution, key points.
+ */
+ public static String generateReviewPage(File[] listOfFiles) {
+ //Assemble output
+ String outputContent = "# Review Page\n\n" +
+ "This page summarize the solutions of all problems. For thoughts,ideas written in English, refer to deach individual solution. \n" +
+ "New problems will be automatically updated once added.\n\n";
+
+ int count = 0;
+ for (File file : listOfFiles) {
+ if (file.getName().contains(".java")) {
+ String convertedFileName = file.getName().replace(" ", "%20");
+ outputContent += "**" + count + ". [" + file.getName() + "](https://github.com/awangdev/LintCode/blob/master/Java/"+ convertedFileName +")**";
+ try {
+ BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream("Java/" + file.getName()), "UTF-8"));
+ String line = null;
+ int countLine = 0;
+ while ((line = reader.readLine()) != null && !line.equals("```")) {
+ if (countLine == 0) {
+ final String trimedLine = line.trim().toUpperCase();
+ if (trimedLine.length() == 1 && !calculateLevel(trimedLine).isEmpty()) {
+ outputContent += " Level: " + calculateLevel(trimedLine) + "\n";
+ } else {
+ outputContent += "\n";
+ }
+ } else if (countLine == 1 && line.indexOf(TUTORIAL_KEY_WORD) == 0) {
+ outputContent += " [Tutorial Link](" + line.substring(TUTORIAL_KEY_WORD.length()) + ")\n";
+ } else {
+ outputContent += line + "\n";
+ }
+ countLine++;
+ }
+ } catch (Exception e) {
+ System.err.format("IOException: %s%n", e);
+ }//end of one file
+ outputContent += "\n---\n";
+ count++;
+ }
+ }
+ return outputContent;
+ }
+
+ private static String calculateLevel(final String level) {
+ switch(level) {
+ case "N" :
+ return "Naive";
+ case "E" :
+ return "Easy";
+ case "M" :
+ return "Medium";
+ case "H" :
+ return "Hard";
+ case "S" :
+ return "Super";
+ }
+ return "";
+ }
}
\ No newline at end of file
diff --git a/Java/2 Sum II - Input array is sorted.java b/Java/2 Sum II - Input array is sorted.java
new file mode 100755
index 0000000..72327c8
--- /dev/null
+++ b/Java/2 Sum II - Input array is sorted.java
@@ -0,0 +1,57 @@
+M
+
+排序好的array. Binary Search移动start和end,核查sum。
+
+
+```
+/*
+Given an array of integers that is already sorted in ascending order,
+find two numbers such that they add up to a specific target number.
+
+The function twoSum should return indices of the two numbers such that they add up to the target,
+where index1 must be less than index2.
+Please note that your returned answers (both index1 and index2) are not zero-based.
+
+You may assume that each input would have exactly one solution.
+
+Input: numbers={2, 7, 11, 15}, target=9
+Output: index1=1, index2=2
+
+Tags: Array Two Pointers, Binary Search
+Similar Problems: (M) Two Sum
+
+*/
+
+
+/*
+Thoughts:
+Do a binary search, but do not over-complicate it:
+Start, end. Check if nums[start] + nums[end] == target.
+binary move it: in fact, moving the two border, 1 position at a time
+*/
+
+public class Solution {
+ public int[] twoSum(int[] nums, int target) {
+ int[] rst = new int[2];
+ if (nums == null || nums.length <= 1) {
+ return rst;
+ }
+ int start = 0;
+ int end = nums.length - 1;
+ while(start < end) {
+ long sum = (long)(nums[start] + nums[end]);
+ if (target == sum) {
+ rst[0] = start + 1;
+ rst[1] = end + 1;
+ break;
+ } else if (target > sum) {
+ start++;
+ } else {
+ end--;
+ }
+ }//END while
+ return rst;
+ }
+}
+
+```
\ No newline at end of file
diff --git a/Java/2 Sum II.java b/Java/2 Sum II.java
new file mode 100755
index 0000000..0db648d
--- /dev/null
+++ b/Java/2 Sum II.java
@@ -0,0 +1,122 @@
+M
+
+LintCode的题. 注意找的是greater/bigger than target。
+
+由于给定条件允许O(nLogn):
+ sort
+ two pointer
+
+while里面two pointer移动。每次如果num[left]+num[right] > target,那么其中所有num[left++]的加上num[right]都>target.
+也就是,num[right]不动,计算加入挪动left能有多少组,那就是: right-left这么多。 全部加到count上去。
+然后right--.换个right去和前面的left部分作比较。
+
+```
+/*
+Given an array of integers, find how many pairs in the array such that
+their sum is bigger than a specific target number. Please return the number of pairs.
+Example
+numbers=[2, 7, 11, 15], target=24
+
+return 1
+
+Challenge
+Either of the following solutions are acceptable:
+
+O(1) Space, O(nlogn) Time
+Tags Expand
+Two Pointers
+
+*/
+
+/*
+Thoughts:
+After doing Trigle Count...Can we just do the same for this, move while pointers to center?
+OMG. The original idea was sooooooo complicated.
+*/
+public class Solution {
+ public int twoSum2(int[] nums, int target) {
+ if (nums == null || nums.length == 0) {
+ return 0;
+ }
+ int count = 0;
+ int left = 0;
+ int right = nums.length - 1;
+ Arrays.sort(nums);
+ while (left < right) {
+ if (nums[left] + nums[right] > target) {
+ count += (right - left);
+ right--;
+ } else {
+ left++;
+ }
+ }
+ return count;
+ }
+}
+
+//Below are bad solutions. Don't worry about them
+
+/*
+
+Thoughts:
+1. For loop to try each element from (i ~ end). O(n)
+2. In for, do binary search on nums[i] + nums[j] > target,
+3. count += (length - j)
+
+Note: when not found, return nums.length, because at then end, (length - length) == 0, which will be added to count.
+Note: Always pin target down, and move mid to compare. Don't get confused
+Also, take care of corner cases.
+*/
+
+public class Solution {
+ public int twoSum2(int[] nums, int target) {
+ if (nums == null || nums.length == 0) {
+ return 0;
+ }
+ int count = 0;
+ Arrays.sort(nums);
+ for (int i = 1; i < nums.length; i++) {
+ int index = binarySearch(nums, target - nums[i - 1], i, nums.length - 1);
+ count += nums.length - index;
+ }
+ return count;
+ }
+
+ public int binarySearch(int[] nums, int target, int start, int end) {
+ int mid;
+ int sum;
+ while (start + 1 < end) {
+ mid = start + (end - start) /2;
+ if (mid - 1 >= 0 && nums[mid-1] <= target && target < nums[mid]) {
+ return mid;
+ } else if (mid + 1 < nums.length && nums[mid] <= target && target < nums[mid + 1]) {
+ return mid + 1;
+ } else if (target < nums[mid]) {
+ end = mid;
+ } else {
+ start = mid;
+ }
+ }
+ if (nums[start] > target) {
+ return start;
+ }
+ return (nums[end] > target) ? end : nums.length;
+ }
+}
+
+//Brutle force, O(n^2)
+public class Solution {
+ public int twoSum2(int[] nums, int target) {
+ if (nums == null || nums.length == 0) {
+ return 0;
+ }
+ int count = 0;
+ for (int i = 0; i < nums.length - 1; i++) {
+ for (int j = i + 1; j < nums.length; j++) {
+ count += (nums[i] + nums[j] > target) ? 1 : 0;
+ }
+ }
+ }
+}
+
+```
\ No newline at end of file
diff --git a/Java/2 Sum.java b/Java/2 Sum.java
old mode 100644
new mode 100755
index 06fea20..1ddbd01
--- a/Java/2 Sum.java
+++ b/Java/2 Sum.java
@@ -1,62 +1,129 @@
-/*
-Given an array of integers, find two numbers such that they add up to a specific target number.
-
-The function twoSum should return indices of the two numbers such that they add up to the target, where index1 must be less than index2. Please note that your returned answers (both index1 and index2) are not zero-based.
-
-Note
-You may assume that each input would have exactly one solution
-
-Example
-numbers=[2, 7, 11, 15], target=9
-
-return [1, 2]
-
-Challenge
-1. O(1) Space, O(nlogn) Time
-
-2. O(n) Space, O(n) Time
-
-Tags Expand
-Array Two Pointers
-
-
-Using a HashMap, O(n) space and O(n) time.
-Thinking process:
-Push everything into a HashMap.
-Check if one element exist in the HashMap, if so save it. Meanwhile, save the other one.
-Trick: after adding into the HashMap, we are looking for the 2nd index first. This is particularly because the way we write the code in optimized form:
- always check (target - current) from the HashMap. If exist, that means index0 has already been pushed into the HashMap and current value is at index1.
-(key, value) = (numbers[i], i)
-Note: return index+1 because this is not 0-based.
-*/
-
-public class Solution {
- /*
- * @param numbers : An array of Integer
- * @param target : target = numbers[index1] + numbers[index2]
- * @return : [index1 + 1, index2 + 1] (index1 < index2)
- */
- //Using HashMap
- public int[] twoSum(int[] numbers, int target) {
- if (numbers == null || numbers.length == 0) {
- return null;
- }
- int[] rst = new int[2];
- HashMap map = new HashMap();
- for (int i = 0; i < numbers.length; i++) {
- if (map.containsKey(target - numbers[i])) {
- rst[0] = map.get(target - numbers[i]) + 1;
- rst[1] = i + 1;
- } else {
- map.put(numbers[i], i);
- }
- }
- return rst;
- }
-}
-
-
-
-//2. O(1) Space O(nlogn) time
-//TODO
-
+M
+tutorial:https://www.youtube.com/watch?v=P8zBxoVY1oI&feature=youtu.be
+
+解法1:相对暴力简洁, HashMap,找到一个value, 存一个; 若在HashMap里面 match 到结果, 就return HashMap里存的index. O(n) space && time.
+
+解法2:Sort array, two pointer 前后++,--搜索。Sort 用时O(nlogn).
+1. 第一步 two pointer 找 value.
+2. 注意,要利用额外的空间保留original array, 用来时候找index. (此处不能用HashMap,因为以value 为key,但value可能重复)
+O(n) space, O(nlogn) time.
+
+
+```
+
+/*
+Given an array of integers, find two numbers such that they add up to a specific target number.
+The function twoSum should return indices of the two numbers such that they add up to the target,
+where index1 must be less than index2.
+Please note that your returned answers (both index1 and index2) are NOT zero-based.
+Example
+numbers=[2, 7, 11, 15], target=9
+return [1, 2]
+Note
+You may assume that each input would have exactly one solution
+Challenge
+Either of the following solutions are acceptable:
+O(n) Space, O(nlogn) Time
+O(n) Space, O(n) Time
+Tags Expand
+Two Pointers Sort Hash Table Array Airbnb Facebook
+*/
+
+/*
+Thoughts:
+ Using a HashMap, O(n) space and O(n) time.
+ Thinking process:
+ Push everything into a HashMap.
+ Check if one element exist in the HashMap, if so save it. Meanwhile, save the other one.
+ Trick: after adding into the HashMap, we are looking for the 2nd index first.
+ Always check (target - current) from the HashMap.
+ If exist, that means index0 has already been pushed into the HashMap and current value is at index1.
+ (key, value) = (numbers[i], i)
+ Note: return index+1 because this is not 0-based.
+*/
+
+public class Solution {
+ //Using HashMap
+ public int[] twoSum(int[] numbers, int target) {
+ if (numbers == null || numbers.length == 0) {
+ return null;
+ }
+ int[] rst = new int[2];
+ HashMap map = new HashMap();
+ for (int i = 0; i < numbers.length; i++) {
+ if (map.containsKey(target - numbers[i])) {
+ rst[0] = map.get(target - numbers[i]) + 1;
+ rst[1] = i + 1;
+ break;
+ } else {
+ map.put(numbers[i], i);
+ }
+ }
+ return rst;
+ }
+}
+
+
+
+//2. O(n) Space O(nlogn) time
+/*
+ Feels like binary search when looking at O(nlogn)
+ 1. sort
+ 2. loop all number
+ 3. binary search on rest
+*/
+public class Solution {
+ public int[] twoSum(int[] numbers, int target) {
+ if (numbers == null || numbers.length == 0) {
+ return null;
+ }
+ int[] original = new int[numbers.length];
+ for (int i = 0; i < numbers.length; i++) {
+ original[i] = numbers[i];
+ }
+
+ Arrays.sort(numbers);
+ int start = 0;
+ int end = numbers.length - 1;
+ int num1 = -1;
+ int num2 = -1;
+ while (start != end) {
+ int sum = numbers[start] + numbers[end];
+ if (sum == target) {
+ num1 = numbers[start];
+ num2 = numbers[end];
+ break;
+ }else if (sum < target) {
+ start++;
+ } else {
+ end--;
+ }
+ }
+
+ //Find the num1,num2 in original array and record the index
+ int[] rst = new int[2];
+ rst[0] = -1;
+ rst[1] = -1;
+ for (int i = 0; i < original.length; i++) {
+ if (original[i] == num1 || original[i] == num2) {
+ if (rst[0] == -1) {
+ rst[0] = i + 1;
+ } else {
+ rst[1] = i + 1;
+ break;
+ }
+ }
+ }
+ return rst;
+ }
+}
+
+
+
+
+
+
+
+
+
+```
\ No newline at end of file
diff --git a/Java/3 Sum Closest.java b/Java/3 Sum Closest.java
index ea4b234..da399e9 100644
--- a/Java/3 Sum Closest.java
+++ b/Java/3 Sum Closest.java
@@ -1,28 +1,33 @@
+M
+
+3Sum 的一种简单形式, 并且都没有找index, value, 而只是找个sum罢了.
+
+double for loop。 2Sum只能用土办法 left/right 2 pointers。 O(n^2)
+
+注意:check closest时候用long, 以免int不够用
+
+```
/*
Given an array S of n integers, find three integers in S such that the sum is closest to a given number, target. Return the sum of the three integers.
-
Note
You may assume that each input would have exactly one solution.
-
Example
For example, given array S = {-1 2 1 -4}, and target = 1. The sum that is closest to the target is 2. (-1 + 2 + 1 = 2).
-
Tags Expand
Two Pointers Sort Array
-Thinking process:
-Similar to 3 SUM.
-Starting from the left-element, assume it's the solution. Move the 2 pointers in the right-side-array.
-Using the two pointers, trying to find ele1 + ele2 + ele3 = closest number to target.
-Note: for comparing closet, use initial value Integer.MAX_VALUE. Be aware of the overflow of integer, use long to handle.
*/
+/*
+Thoughts:
+ Similar to 3 SUM.
+ Starting from the left-element, assume it's the solution. Move the 2 pointers in the right-side-array.
+ Using the two pointers, trying to find ele1 + ele2 + ele3 = closest number to target.
+ Note: for comparing closet, use initial value Integer.MAX_VALUE. Be aware of the overflow of integer, use long to handle.
+
+*/
public class Solution {
- /**
- * @param numbers: Give an array numbers of n integer
- * @param target : An integer
- * @return : return the sum of the three integers, the sum closest target.
- */
+
public int threeSumClosest(int[] num, int target) {
if (num == null || num.length < 3) {
return Integer.MAX_VALUE;
@@ -49,3 +54,4 @@ public int threeSumClosest(int[] num, int target) {
}
}
+```
\ No newline at end of file
diff --git a/Java/3 Sum Smaller.java b/Java/3 Sum Smaller.java
new file mode 100644
index 0000000..55642b1
--- /dev/null
+++ b/Java/3 Sum Smaller.java
@@ -0,0 +1,58 @@
+一般的O(n3)肯定不行。在此基础上优化。
+发现j,k满足条件时候,(k - j)就是所有 sum target, 又因为j不能后退,只能k--,那么问题就被锁定了. 这样可以做到O(n2)
+```
+/*
+Given an array of n integers nums and a target, find the number of index triplets i, j, k with 0 <= i < j < k < n that satisfy the condition nums[i] + nums[j] + nums[k] < target.
+
+For example, given nums = [-2, 0, 1, 3], and target = 2.
+
+Return 2. Because there are two triplets which sums are less than 2:
+
+[-2, 0, 1]
+[-2, 0, 3]
+
+Follow up:
+Could you solve it in O(n2) runtime?
+
+Tags: Array Two Pointers
+Similar Problems:(M) 3Sum, (M) 3Sum Closest
+
+*/
+
+
+/*
+Thoughts:
+Similar to 3 sum, but ofcourse, this one check on '<' so we can not use HashMap anymore.
+Basic concept is to fix first number, then check for the rest two numbers, see if they addup < target.
+When checking j and k, realize something nice:
+ if nums[j] + nums[k] < target - nums[i], that means for all index <= k will work, so directly add (k - j) to result (that's: index = j+1, j+2, ....,k)
+ also, move j forward for next round.
+OR, if three-add-up >= target, since j can only increase, we do k-- to make the three-add-up smaller
+
+Note:
+Don't forget to sort, otherwise the sequence/order is unpredictable
+*/
+public class Solution {
+ public int threeSumSmaller(int[] nums, int target) {
+ if (nums == null || nums.length <= 2) {
+ return 0;
+ }
+ Arrays.sort(nums);
+ int rst = 0;
+ for (int i = 0; i < nums.length - 2; i++) {
+ int j = i + 1;
+ int k = nums.length - 1;
+ while (j < k) {
+ if (nums[i] + nums[j] + nums[k] >= target) {
+ k--;
+ } else {
+ rst += (k - j);
+ j++;
+ }
+ }
+ }//END for
+ return rst;
+ }
+}
+```
\ No newline at end of file
diff --git a/Java/3 Sum.java b/Java/3 Sum.java
index df0a63e..e84bc84 100644
--- a/Java/3 Sum.java
+++ b/Java/3 Sum.java
@@ -1,44 +1,61 @@
-/*
-Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.
+M
-Note
-Elements in a triplet (a,b,c) must be in non-descending order. (ie, a = b = c)
+用个for loop 加上 2sum 的土办法。
-The solution set must not contain duplicate triplets.
+注意:
+ 1. 找 value triplets, 多个结果。注意,并非找index。
+ 2. 要升序, 第一层for loop 从最后一个元素挑起, 保证了顺序。
+ 3. 去掉duplicate: check用过的同样的数字,都跳掉。不需要用同样的数字再计算一边已有结果。
+
+步骤:
+ 1. For loop 挑个数字A.
+ 2. 2Sum 出一堆2个数字的结果
+ 3. Cross match 步骤1里面的A.
+
+时间 O(n^2), 两个nested loop
+
+
+另外, 还是可以用HashMap来做2Sum。稍微短点。还是要注意handle duplicates.
+
+再另外(leetcode做时写的):先sort,然后two pointer。
+
+```
+/*
+Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0?
+Find all unique triplets in the array which gives the sum of zero.
Example
For example, given array S = {-1 0 1 2 -1 -4}, A solution set is:
(-1, 0, 1)
-
(-1, -1, 2)
+Note
+Elements in a triplet (a,b,c) must be in non-descending order. (ie, a ≤ b ≤ c)
+
+The solution set must not contain duplicate triplets.
Tags Expand
-Two Pointers Sort Array
-
-Thinking process:
-Cannot use HashMap for this problem because of the duplicates. See the bottom of this file for the failed version.
-Remember to check for null and edge-soluton.
-Before everything, Arrays.sort() the given array, in order to effectively handle the duplicates.
-At 3SUM level, takes 1 element out and do 2SUM on the rest of the front elements of the array. Note, 2SUM has multitple solutions (need to handle duplicates)
-Cross-match the 2SUM solution with the selected element from 3SUM level.
+Two Pointers Sort Array Facebook
*/
+/*
+Thoughts:
+ Remember to check for null and edge-soluton.
+ Before everything, Arrays.sort() the given array, in order to effectively handle the duplicates.
+ At 3SUM level, takes 1 element out and do 2SUM on the rest of the front elements of the array. Note, 2SUM has multitple solutions (need to handle duplicates)
+ Cross-match the 2SUM solution with the selected element from 3SUM level.
+*/
public class Solution {
- /**
- * @param numbers : Give an array numbers of n integer
- * @return : Find all unique triplets in the array which gives the sum of zero.
- */
public ArrayList> threeSum(int[] numbers) {
ArrayList> rst = new ArrayList>();
if (numbers == null && numbers.length <= 2) {// Length at least >= 3
return rst;
}
Arrays.sort(numbers);//Sort in order to handle duplicates
- for (int i = numbers.length - 1; i >= 2; i--) {// i >=2 because at least 3 element in result.
+ for (int i = numbers.length - 1; i >= 2; i--) {// i >=2 because at least 3 element in result; starting from end, ensures non-descending order
if (i < numbers.length - 1 && numbers[i] == numbers[i + 1]) {
- continue;//The case of numbers[i + 1] should have already covered all possibilities of the case numbers[i], so safe to skip
+ continue;//The case of numbers[i + 1]: should have already covered all possibilities of the case numbers[i], so safe to skip
}
ArrayList> twoSum = calTwoSum(numbers, i - 1, 0 - numbers[i]);//Pick the 3rd element numbers[i]
for (int j = 0; j < twoSum.size(); j++) {//Find two sum of rest-front elements. Cross add them with numbers[i]
@@ -51,9 +68,6 @@ public ArrayList> threeSum(int[] numbers) {
//Two Sum. Multiple answer
public ArrayList> calTwoSum(int[] num, int end, int target) {
ArrayList> rst = new ArrayList>();
- if (num == null || num.length <= 1) {//Length at least >= 2
- return rst;
- }
int left = 0;
int right = end;
while (left < right) {
@@ -83,42 +97,118 @@ public ArrayList> calTwoSum(int[] num, int end, int target) {
}
-
-
-
+/*
+ Thoughts:
+ Exact same approach, except using HashMap in 2Sum
+*/
+//With HashMap 2Sum
+public class Solution {
+ public ArrayList> threeSum(int[] numbers) {
+ ArrayList> rst = new ArrayList>();
+ if (numbers == null && numbers.length <= 2) {// Length at least >= 3
+ return rst;
+ }
+ Arrays.sort(numbers);//Sort in order to handle duplicates
+ for (int i = numbers.length - 1; i >= 2; i--) {// i >=2 because at least 3 element in result; starting from end, ensures non-descending order
+ if (i < numbers.length - 1 && numbers[i] == numbers[i + 1]) {
+ continue;//The case of numbers[i + 1]: should have already covered all possibilities of the case numbers[i], so safe to skip
+ }
+ ArrayList> twoSum = calTwoSum(numbers, i - 1, 0 - numbers[i]);//Pick the 3rd element numbers[i]
+ for (int j = 0; j < twoSum.size(); j++) {//Find two sum of rest-front elements. Cross add them with numbers[i]
+ twoSum.get(j).add(numbers[i]);
+ }
+ rst.addAll(twoSum);
+ }
+ return rst;
+ }
+ //Two Sum. Multiple answer, with HashMap
+ public ArrayList> calTwoSum(int[] num, int end, int target) {
+ ArrayList> rst = new ArrayList>();
+ ArrayList match;
+ HashMap map = new HashMap();
+ for (int i = 0; i <= end; i++) {
+ if (map.containsKey(num[i])) {
+ match = new ArrayList();
+ match.add(num[map.get(num[i])]);
+ match.add(num[i]);
+ if (!rst.contains(match)) {
+ rst.add(new ArrayList(match));
+ }
+ } else {
+ map.put(target - num[i], i);
+ }
+ //Skip duplicate
+ if (i < end && num[i] == num[i + 1]) {
+ continue;
+ }
+ }
+ return rst;
+ }
+}
/*
-The following is a exceeding time version.
-I believe the concept is clear, but it does not handle duplicates well. So we can't use this version.
+ From LeetCode Solution
+ Thoughts:
+ sort list. O(nLogn)
+ end: n^2
+ for (i = 0 ~ n) {
+ int target = 0 - nums[i];
+ while (start + 1 < end) {
+ start + end == target {
+ rst.add(i, star, end);
+ keep looking: start ++, end--
+ }
+ else start + end < target?
+ start++
+ else
+ end--;
+ }
+ }
+ }
+Note:
+ Check duplicates. Compute a unique string to savei set
+*/
public class Solution {
- public ArrayList> threeSum(int[] numbers) {
- ArrayList> rst = new ArrayList>();
- if (numbers.length <= 2) {
+ public List> threeSum(int[] nums) {
+ List> rst = new ArrayList>();
+ if (nums == null || nums.length == 0) {
return rst;
}
- Arrays.sort(numbers);
- for (int i = 0; i < numbers.length; i++){
- HashMap map = new HashMap();
- for (int j = i; j < numbers.length; j++) {
- int remain = 0 - numbers[i] - numbers[j];
- if (map.containsKey(remain) && map.get(remain) != i) {
- ArrayList list = new ArrayList();
- list.add(numbers[i]);
- list.add(remain);
- list.add(numbers[j]);
- if (!rst.contains(list)){
- rst.add(list);
- }
+
+ Arrays.sort(nums);
+ HashSet set = new HashSet();
+ //use old target to check duplicates. instead of set.
+ for (int i = 0; i < nums.length - 2; i++) {
+ int target = 0 - nums[i];
+ int start = i + 1;
+ int end = nums.length - 1;
+
+ ArrayList list = new ArrayList();
+ while (start < end) {
+ if (nums[start] + nums[end] == target &&
+ !set.contains(nums[i] + "," + nums[start] + "," + nums[end])) {
+ list.add(nums[i]);
+ list.add(nums[start]);
+ list.add(nums[end]);
+ rst.add(list);
+ set.add(nums[i] + "," + nums[start] + "," + nums[end]);
+ list = new ArrayList();
+ start++;
+ end--;
+ } else if (nums[start] + nums[end] < target) {
+ start++;
} else {
- map.put(numbers[j], j);
+ end--;
}
- }
+ }//end while
}
+
return rst;
}
}
-*/
\ No newline at end of file
+
+```
\ No newline at end of file
diff --git a/Java/4 Sum.java b/Java/4 Sum.java
old mode 100644
new mode 100755
index 7426ba2..f8fee31
--- a/Java/4 Sum.java
+++ b/Java/4 Sum.java
@@ -1,81 +1,230 @@
-/*
-Given an array S of n integers, are there elements a, b, c, and d in S such that a + b + c + d = target? Find all unique quadruplets in the array which gives the sum of target.
-
-Example
-For example, given array S = {1 0 -1 0 -2 2}, and target = 0. A solution set is:
-
-(-1, 0, 0, 1)
-
-(-2, -1, 1, 2)
-
-(-2, 0, 0, 2)
-
-Note
-Elements in a quadruplet (a,b,c,d) must be in non-descending order. (ie, a ≤ b ≤ c ≤ d)
-
-The solution set must not contain duplicate quadruplets.
-
-Tags Expand
-Two Pointers Sort Hash Table Array
-
-Thinking process:
-Perform another layer outsideo of 3SUM.
-
-Note: If try to divide and perform two 2SUM, it will be a bit difficult. Refer to http://blog.csdn.net/linhuanmars/article/details/24826871
-*/
-
-public class Solution {
- /**
- * @param numbers : Give an array numbersbers of n integer
- * @param target : you need to find four elements that's sum of target
- * @return : Find all unique quadruplets in the array which gives the sum of
- * zero.
- */
- public ArrayList> fourSum(int[] numbers, int target) {
- ArrayList> rst = new ArrayList>();
- if(numbers == null || numbers.length < 4) {
- return rst;
- }
- Arrays.sort(numbers);
- //Pick 1st element
- for (int i = 0; i < numbers.length - 3; i++) {
- if (i != 0 && numbers[i] == numbers[i - 1]) {//Check for duplicate of 1st element
- continue;
- }
- //Pick 2nd element
- for (int j = i + 1; j < numbers.length - 2; j++) {
- if (j != i + 1 && numbers[j] == numbers[j - 1]) {//Check for duplicate of 2nd element
- continue;
- }
- //Pick 3rd and 4th element
- int third = j + 1;
- int fourth = numbers.length - 1;
- while (third < fourth) {
- int sum = numbers[i] + numbers[j] + numbers[third] + numbers[fourth];
- if (sum < target) {
- third++;
- } else if (sum > target) {
- fourth--;
- } else {//sum == target
- ArrayList list = new ArrayList();
- list.add(numbers[i]);
- list.add(numbers[j]);
- list.add(numbers[third]);
- list.add(numbers[fourth]);
- rst.add(list);
- third++;
- fourth--;
- while (third < fourth && numbers[third] == numbers[third - 1]) {
- third++;
- }
- while (third < fourth && numbers[fourth] == numbers[fourth + 1]){
- fourth--;
- }
- }
- }
- }
- }
- return rst;
- }
-}
-
+M
+
+方法1: 3Sum外面再加一层. 参考3Sum. 时间O(n^3)。 但此方法在k-sum时候,无疑过于费时间. O(n^k)
+
+方法2: 参见 http://lifexplorer.me/leetcode-3sum-4sum-and-k-sum/
+ 1. 利用2Sum的原理,把4Sum分为连个2Sum。左一个pair,右一个pair,每个pair里面放2个数字。
+ 2. 以一个点,i,作为分界口,也要列举出所有i之前的pair,作为基础。
+ 3. 再尝试从所有i+1后面,找合适的2nd pair。
+
+ 注意:在造class Pair时候,要做@override的function: hashCode(), equals(Object d). 平时不太想得起来用。
+
+```
+/*
+Given an array S of n integers, are there elements a, b, c, and d in S such that a + b + c + d = target?
+
+Find all unique quadruplets in the array which gives the sum of target.
+
+Example
+Given array S = {1 0 -1 0 -2 2}, and target = 0. A solution set is:
+
+(-1, 0, 0, 1)
+(-2, -1, 1, 2)
+(-2, 0, 0, 2)
+Note
+Elements in a quadruplet (a,b,c,d) must be in non-descending order. (ie, a ≤ b ≤ c ≤ d)
+The solution set must not contain duplicate quadruplets.
+
+Tags Expand
+Two Pointers Sort Hash Table Array
+
+*/
+
+/*
+Thoughts
+Perform another layer outside of 3SUM. O(n^3).
+Note: If try to divide and perform two 2SUM, it will be a bit difficult. Refer to http://blog.csdn.net/linhuanmars/article/details/24826871
+
+*/
+public class Solution {
+
+ public ArrayList> fourSum(int[] numbers, int target) {
+ ArrayList> rst = new ArrayList>();
+ if(numbers == null || numbers.length < 4) {
+ return rst;
+ }
+ Arrays.sort(numbers);
+ //Pick 1st element
+ for (int i = 0; i < numbers.length - 3; i++) {
+ if (i != 0 && numbers[i] == numbers[i - 1]) {//Check for duplicate of 1st element
+ continue;
+ }
+ //Pick 2nd element
+ for (int j = i + 1; j < numbers.length - 2; j++) {
+ if (j != i + 1 && numbers[j] == numbers[j - 1]) {//Check for duplicate of 2nd element
+ continue;
+ }
+ //Pick 3rd and 4th element
+ int third = j + 1;
+ int fourth = numbers.length - 1;
+ while (third < fourth) {
+ int sum = numbers[i] + numbers[j] + numbers[third] + numbers[fourth];
+ if (sum < target) {
+ third++;
+ } else if (sum > target) {
+ fourth--;
+ } else {//sum == target
+ ArrayList list = new ArrayList();
+ list.add(numbers[i]);
+ list.add(numbers[j]);
+ list.add(numbers[third]);
+ list.add(numbers[fourth]);
+ rst.add(list);
+ third++;
+ fourth--;
+ while (third < fourth && numbers[third] == numbers[third - 1]) {
+ third++;
+ }
+ while (third < fourth && numbers[fourth] == numbers[fourth + 1]){
+ fourth--;
+ }
+ }
+ }
+ }
+ }
+ return rst;
+ }
+}
+
+
+/*
+NOT Complete yet. Has a order issue in HashSet
+http://lifexplorer.me/leetcode-3sum-4sum-and-k-sum/
+Thoughts:
+Utilize 2Sum.
+
+*/
+
+public class Solution {
+ //Create class Pair for HashSet to use
+ class Pair {
+ Integer x;
+ Integer y;
+
+ public Pair(int x, int y){
+ this.x = x;
+ this.y = y;
+ }
+
+ @Override
+ public int hashCode(){
+ return this.x.hashCode() + this.y.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object d) {
+ if (!(d instanceof Pair)) {
+ return false;
+ }
+ Pair p = (Pair)d;
+ return (this.x == p.x) && (this.y == p.y);
+ }
+ }
+
+ public ArrayList> fourSum(int[] numbers, int target) {
+ ArrayList> rst = new ArrayList>();
+ if (numbers == null || numbers.length < 4) {
+ return rst;
+ }
+ Arrays.sort(numbers);
+ HashMap> map = new HashMap>();
+ for (int i = 0; i < numbers.length; i++) {
+ for (int j = i + 1; j < numbers.length; j++) {
+ int sum = numbers[i] + numbers[j];
+ if (map.containsKey(target - sum)) {
+ for (Pair p : map.get(target - sum)) {
+ ArrayList list = new ArrayList();
+ list.add(p.x);
+ list.add(p.y);
+ list.add(numbers[i]);
+ list.add(numbers[j]);
+ if (!rst.contains(list)) {
+ rst.add(list);
+ }
+ }
+ }
+ }
+ //Add all pairs up to i
+ for (int j = 0; j < i; j++) {
+ int sum = numbers[i] + numbers[j];
+ if (!map.containsKey(sum)) {
+ map.put(sum, new HashSet());
+ }
+ map.get(sum).add(new Pair(numbers[j], numbers[i]));
+ }
+ }
+
+ return rst;
+ }
+
+}
+
+
+
+public class Solution {
+ //Create class Pair for HashSet to use
+ class Pair {
+ Integer x;
+ Integer y;
+
+ public Pair(int x, int y){
+ this.x = x;
+ this.y = y;
+ }
+
+ @Override
+ public int hashCode(){
+ return this.x.hashCode() + this.y.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object d) {
+ if (!(d instanceof Pair)) {
+ return false;
+ }
+ Pair p = (Pair)d;
+ return (this.x == p.x) && (this.y == p.y);
+ }
+ }
+
+ public ArrayList> fourSum(int[] numbers, int target) {
+ ArrayList> rst = new ArrayList>();
+ if (numbers == null || numbers.length < 4) {
+ return rst;
+ }
+ Arrays.sort(numbers);
+ HashMap> map = new HashMap>();
+ for (int i = 0; i < numbers.length; i++) {
+ for (int j = i + 1; j < numbers.length; j++) {
+ int sum = numbers[i] + numbers[j];
+ if (map.containsKey(target - sum)) {
+ for (Pair p : map.get(target - sum)) {
+ ArrayList list = new ArrayList();
+ list.add(p.x);
+ list.add(p.y);
+ list.add(numbers[i]);
+ list.add(numbers[j]);
+ if (!rst.contains(list)) {
+ rst.add(list);
+ }
+ }
+ }
+ }
+ //Add all pairs up to i
+ for (int j = 0; j < i; j++) {
+ int sum = numbers[i] + numbers[j];
+ if (!map.containsKey(sum)) {
+ map.put(sum, new ArrayList());
+ }
+ map.get(sum).add(new Pair(numbers[j], numbers[i]));
+ }
+ }
+
+ return rst;
+ }
+
+}
+
+
+
+```
\ No newline at end of file
diff --git a/Java/A+B.java b/Java/A+B.java
index 61eaebc..5607c11 100644
--- a/Java/A+B.java
+++ b/Java/A+B.java
@@ -1,30 +1,48 @@
-/*
-For given numbers a and b in function aplusb, return the sum of them.
+E
-Note
-You don't need to parse the input and output. Just calculate and return.
+^ 是不完全加法. 每次都忽略了进位。而 & 刚好可以算出需要的所有进位。
+
+那么就,首先记录好进位的数字:carry. 然后 a^b 不完全加法一次。然后b用来放剩下的carry, 每次移动一位,继续加,知道b循环为0为止。
+
+Bit Operation
+Steps:
+ a & b: 每bit可能出得余数
+ a ^ b: 每bit在此次操作可能留下的值,XOR 操作
+ 每次左移余数1位,然后存到b, 再去跟a做第一步。loop until b == 0
+
+(http://www.meetqun.com/thread-6580-1-1.html)
+
+```
+/*
+Write a function that add two numbers A and B. You should not use + or any arithmetic operators.
Example
-If a=1 and b=2 return 3
+Given a=1 and b=2 return 3
+
+Note
+There is no need to read data from standard input stream. Both parameters are given in function aplusb, you job is to calculate the sum and return it.
Challenge
-Can you do it with out + operation?
+Of course you can just return a + b to get accepted. But Can you challenge not do it like that?
Clarification
Are a and b both 32-bit integers?
- - Yes.
+Yes.
+Can I use bit operation?
+
+Sure you can.
+Tags Expand
+Cracking The Coding Interview Bit Manipulation
+
-Thinking process:
-Bit operation. Just to remmeber this problem, doing A+B using bit.
*/
+/*
+Thought:
+ Bit operation. Just to remmeber this problem, doing A+B using bit.
+*/
class Solution {
- /*
- * param a: The first integer
- * param b: The second integer
- * return: The sum of a and b
- */
public int aplusb(int a, int b) {
while (b != 0) {
int carry = a & b;
@@ -35,3 +53,5 @@ public int aplusb(int a, int b) {
}
};
+
+```
\ No newline at end of file
diff --git a/Java/Add Binary.java b/Java/Add Binary.java
index e8d1f35..3bbd79f 100644
--- a/Java/Add Binary.java
+++ b/Java/Add Binary.java
@@ -1,4 +1,14 @@
+E
+
+方法一:土办法没技术,把binary换成数字,加起来,再换成binary。如果input很大,那么很可能int,long都hold不住。不保险。
+
+方法二:一般方法,string化为charArray,然后逐位加起,最后记得处理多余的一个carry on
+
+
+```
/*
+Add Binary
+
Given two binary strings, return their sum (also a binary string).
Example
@@ -9,10 +19,13 @@ Given two binary strings, return their sum (also a binary string).
Return 100
Tags Expand
-String Binary
+String Binary Facebook
+
+*/
+/*
//Thougths:
1. Turn string binary format into integer
2. add integer
@@ -20,7 +33,6 @@ Given two binary strings, return their sum (also a binary string).
Note: this just test if we know how to manipulate string/binary/Integer
*/
-
public class Solution {
/**
* @param a a number
@@ -39,3 +51,40 @@ public String addBinary(String a, String b) {
return Integer.toBinaryString(sum);
}
}
+
+
+
+/*
+ Thought:
+ Use binary property, add all and move carry-on
+ String to charArray
+*/
+
+public class Solution {
+ public String addBinary(String a, String b) {
+ if (a == null || b == null || a.length() == 0 || b.length() == 0) {
+ return null;
+ }
+ char[] shortArr = a.length() < b.length() ? a.toCharArray() : b.toCharArray();
+ char[] longArr = a.length() < b.length() ? b.toCharArray() : a.toCharArray();
+ int carry = 0;
+ int shortVal = 0;
+ int nextCarry = 0;
+ int diff = longArr.length - shortArr.length;
+ for (int i = longArr.length - 1; i >= 0; i--) {
+ shortVal = (i - diff) >= 0 ? shortArr[i - diff] - '0': 0;
+ nextCarry = (longArr[i] - '0' + shortVal + carry) / 2;
+ longArr[i] =(char)((longArr[i] - '0' + shortVal + carry) % 2 + '0');
+ carry = nextCarry;
+ }
+
+ if (carry != 0) {
+ return "1" + new String(longArr);
+ }
+
+ return new String(longArr);
+ }
+}
+
+
+```
\ No newline at end of file
diff --git a/Java/Add Two Numbers II.java b/Java/Add Two Numbers II.java
index 55d3fba..5b3a138 100644
--- a/Java/Add Two Numbers II.java
+++ b/Java/Add Two Numbers II.java
@@ -1,9 +1,13 @@
-方向相反。巧用stack.
+M
+
+LinkedList并没有反过来,那么自己反:
+ 方向相反。巧用stack.
+
+做加法都一样:
+ 1. carrier
+ 2. carrier = (rst + carrier) / 10
+ 3. rst = (rst + carrier) % 10
-做加法都一样:
-1. carrier
-2. carrier = (rst + carrier) / 10
-3. rst = (rst + carrier) % 10
```
/*
You have two numbers represented by a linked list, where each node contains a single digit.
diff --git a/Java/Add Two Numbers.java b/Java/Add Two Numbers.java
new file mode 100644
index 0000000..116250e
--- /dev/null
+++ b/Java/Add Two Numbers.java
@@ -0,0 +1,73 @@
+E
+
+LinkedList都已经反转好了,直接做。
+
+遍历两个l1,l2把carry-on处理好,每次生成一个新node,最后检查carry-on。
+
+跟Add Binary的理解方式一模一样。
+
+
+```
+/*
+You have two numbers represented by a linked list,
+where each node contains a single digit.
+The digits are stored in reverse order,
+such that the 1's digit is at the head of the list.
+Write a function that adds the two numbers and returns the sum as a linked list.
+
+Example
+Given 7->1->6 + 5->9->2. That is, 617 + 295.
+
+Return 2->1->9. That is 912.
+
+Given 3->1->5 and 5->9->2, return 8->0->8.
+
+Tags Expand
+Cracking The Coding Interview Linked List High Precision
+*/
+
+
+/**
+ * Definition for singly-linked list.
+ * public class ListNode {
+ * int val;
+ * ListNode next;
+ * ListNode(int x) {
+ * val = x;
+ * next = null;
+ * }
+ * }
+ */
+public class Solution {
+ /**
+ * @param l1: the first list
+ * @param l2: the second list
+ * @return: the sum list of l1 and l2
+ */
+ public ListNode addLists(ListNode l1, ListNode l2) {
+ ListNode rst = new ListNode(0);
+ ListNode dummy = rst;
+ int carrier = 0;
+ //while
+ while (l1 != null || l2 != null) {
+ if (l1 != null) {
+ carrier += l1.val;
+ l1 = l1.next;
+ }
+ if (l2 != null) {
+ carrier += l2.val;
+ l2 = l2.next;
+ }
+ rst.next = new ListNode(carrier % 10);
+ carrier = carrier / 10;
+ rst = rst.next;
+ }
+ //check the carrier
+ if (carrier == 1) {
+ rst.next = new ListNode(1);
+ }
+ return dummy.next;
+ }
+}
+
+```
\ No newline at end of file
diff --git a/Java/Add and Search Word.java b/Java/Add and Search Word.java
old mode 100644
new mode 100755
index 8d8f0bf..b55a693
--- a/Java/Add and Search Word.java
+++ b/Java/Add and Search Word.java
@@ -1,39 +1,38 @@
-Trie结构, prefix tree.
-节点里面有char, isEnd, HashMap
-记得怎么造trie:无增有移,没node就加,有Node就移动。
-寻找word也一样,无错有移。
+M
+
+Trie结构, prefix tree的变形: '.'可以代替任何字符,那么就要iterate这个node所有的children.
+
+节点里面有char, isEnd, HashMap
+Build trie = Insert word:没node就加,有node就移动。
+Search word:没有node就报错. 到结尾return true
+
+这题因为'.'可以代替任何possible的字符,没一种都是一个新的path,所以recursive做比较好些。
+(iterative就要queue了,麻烦点)
+
```
/*
-Design a data structure that supports the following two operations:
+Design a data structure that supports the following two operations: addWord(word) and search(word)
-void addWord(word)
+search(word) can search a literal word or a regular expression string containing only letters a-z or ..
-bool search(word)
-
-search(word) can search a literal word or a regular expression string containing only letters a-z or ..
A . means it can represent any one letter.
Example
addWord("bad")
-
addWord("dad")
-
addWord("mad")
-
-search("pad") -> false
-
-search("bad") -> true
-
-search(".ad") -> true
-
-search("b..") -> true
-
+search("pad") // return false
+search("bad") // return true
+search(".ad") // return true
+search("b..") // return true
Note
You may assume that all words are consist of lowercase letters a-z.
-Tags:
-Backtracking
+Tags Expand
+Trie
*/
+
+
/*
Build the WordDictionary like a TrieTree.
Note: the '.' indicates any letter, which means we'd have to traverse through all possible letters in current level.
@@ -43,8 +42,6 @@ bool search(word)
TrieNode contains that char, boolean, and HashMap of children
*/
-//NOT DONE YET: http://www.lintcode.com/en/problem/add-and-search-word/#
-
public class WordDictionary {
class TrieNode{
HashMap children;
@@ -108,17 +105,4 @@ public boolean searchHelper(TrieNode root, String word, int index) {
// wordDictionary.search("pattern");
-
-
-
-
-
-
-
-
-
-
-
-
-
```
\ No newline at end of file
diff --git a/Java/Alien Dictionary.java b/Java/Alien Dictionary.java
new file mode 100755
index 0000000..9feb681
--- /dev/null
+++ b/Java/Alien Dictionary.java
@@ -0,0 +1,64 @@
+H
+
+Not Done yet。 Topological sort.
+
+```
+
+/*
+There is a new alien language which uses the latin alphabet.
+However, the order among letters are unknown to you.
+You receive a list of words from the dictionary, where words are sorted lexicographically by the rules of this new language.
+Derive the order of letters in this language.
+
+For example,
+Given the following words in dictionary,
+
+[
+ "wrt",
+ "wrf",
+ "er",
+ "ett",
+ "rftt"
+]
+The correct order is: "wertf".
+
+Note:
+You may assume all letters are in lowercase.
+If the order is invalid, return an empty string.
+There may be multiple valid order of letters, return any one of them is fine.
+Hide Company Tags Google Facebook
+Hide Tags Graph Topological Sort
+Hide Similar Problems (M) Course Schedule II
+
+*/
+
+/*
+ NOT DONE
+ Thoughts:
+ They have sink node. They form a valid tree, without sycle.
+ A char can visit another node, does not mean they have order.
+ A char appear in a lower row means they have different order.
+ For 1st column, w appears before e, e appears before r.
+ For 2nd column:r appears before t, t appears before f
+ For 3rd col: t appears before f.
+ For 4th col, nothing to compare.
+ So make in[][]: [w,e] [e,r][r,t][t,f] based on the possible order.
+
+ Then do topological sort on the sequence and mark the sequence like in course schedule II
+*/
+
+public class Solution {
+ public String alienOrder(String[] words) {
+
+ }
+}
+
+
+
+
+
+
+
+
+
+```
\ No newline at end of file
diff --git a/Java/Anagrams.java b/Java/Anagrams.java
old mode 100644
new mode 100755
index 2d1395c..bd0729e
--- a/Java/Anagrams.java
+++ b/Java/Anagrams.java
@@ -1,22 +1,29 @@
-hashtable 的做法。
-toCharArray
-Arrays.sort
-Stirng.valueOf(char[])
+M
+1. HashMap 的做法. sort每个string, 存进HashMap, 重复的就是anagrams,最后输出。
+ toCharArray
+ Arrays.sort
+ Stirng.valueOf(char[])
+ 时间n*L*O(logL),L是最长string的长度。
-http://www.jiuzhang.com/solutions/anagrams/
-做法不太一样 lOl
-1. take each string, count the occurrance of the 26 letters. save in int[]count.
-2. hash the int[] count and output a unique hash value.
- hash = hash * a + num
- a = a * b.
-3. save to hashmap in the same way as we do.
+2. Arrays.toString(arr)的做法。arr是int[26], assuming only have 26 lowercase letters.
+Count occurrance, 然后convert to String,作为map的key.
+Time complexity: nO(L)
+
+3. 另一种做法:http://www.jiuzhang.com/solutions/anagrams/
+ 1. take each string, count the occurrance of the 26 letters. save in int[]count.
+ 2. hash the int[] count and output a unique hash value.
+ hash = hash * a + num
+ a = a * b.
+ 3. save to hashmap in the same way as we do.
+
+这一步把for s: strs 里面的时间复杂度降到了O(L). L = s.length().
+Need to work on the getHash() function.
+
+时间变成n*O(L). Better.
-这一步把for s: strs
-里面的时间复杂度降到了O(L). L = s.length()
-而普通的,for 里面的时间复杂度是 Llog(L)
```
/*
Given an array of strings, return all groups of strings that are anagrams.
@@ -35,6 +42,44 @@
*/
+/*
+//2.29.2016
+ use int[26] assuming it's all lowercase letters
+ count each string char in a letter array int[], convert the array into string.
+ HashMap carray string as key, and actualy string as value
+ outupt all values
+*/
+public class Solution {
+ public List anagrams(String[] strs) {
+ List rst = new ArrayList();
+ if (strs == null || strs.length == 0) {
+ return rst;
+ }
+ HashMap> map = new HashMap>();
+
+ for (int i = 0; i < strs.length; i++) {
+ int[] arr = new int[26];
+ for (int j = 0; j < strs[i].length(); j++) {
+ arr[strs[i].charAt(j) - 'a'] += 1;
+ }
+ String arrString = Arrays.toString(arr);
+ if (!map.containsKey(arrString)) {
+ map.put(arrString, new ArrayList());
+ }
+ map.get(arrString).add(strs[i]);
+ }
+
+ //Output
+ for (Map.Entry> entry : map.entrySet()) {
+ if (entry.getValue().size() >= 2)
+ rst.addAll(entry.getValue());
+ }
+
+ return rst;
+ }
+}
+
+
/*
Recap 12.09.2015
diff --git a/Java/Backpack II.java b/Java/Backpack II.java
index c780c23..74f50ea 100644
--- a/Java/Backpack II.java
+++ b/Java/Backpack II.java
@@ -1,16 +1,24 @@
-做了backpack I, 这个就如出一辙。
-想法还是,选了A[i-1] 或者没选A[i].
-一路往前跑不回头。就出来了。
+M
+
+做了Backpack I, 这个就如出一辙。
+想法还是,选了A[i-1] 或者没选A[i].
+一路往前跑不回头。就出来了。
+其实这个Backpack II 还更容易看懂代码。
+
+O(m)的做法:
+想想,的确我们只care 最后一行,所以一个存value的就够了。
+注意:和bakcpackI的 O(m)一样的,j是倒序的。如果没有更好的j,就不要更新。就是这个道理。
-O(m)的做法。想想,的确我们只care 最后一行,所以一个存value的就够了。 注意:和bakcpackI的 O(m)一样的,j是倒序的。如果没有更好的j,就不要更新。就是这个道理。
```
/*
-Given n items with size Ai and value Vi, and a backpack with size m. What's the maximum value can you put into the backpack?
+Given n items with size Ai and value Vi, and a backpack with size m.
+What's the maximum value can you put into the backpack?
Example
-Given 4 items with size [2, 3, 5, 7] and value [1, 5, 2, 4], and a backpack with size 10. The maximum value is 9.
+Given 4 items with size [2, 3, 5, 7] and value [1, 5, 2, 4], and a backpack with size 10.
+The maximum value is 9.
Note
You cannot divide item into small pieces and the total size of items you choose should smaller or equal to m.
@@ -79,11 +87,12 @@ public int backPackII(int m, int[] A, int V[]) {
/*
To use just O(m) sapce.
- Just like in Backpack I, at the end, we only care about the last row. Why not just maintain a row, always keep the max value.
+ Just like in Backpack I, at the end, we only care about the last row.
+ Why not just maintain a row, always keep the max value.
Note: Only update dp[j] if adding A[i-1] would be greater than current dp[j]
- It's a bit hard to come up with this... but it's good exercise to build brain a bit.
+ It's a bit hard to come up with this... but it's good exercise.
*/
public class Solution {
@@ -110,6 +119,4 @@ public int backPackII(int m, int[] A, int V[]) {
-
-
```
\ No newline at end of file
diff --git a/Java/Backpack.java b/Java/Backpack.java
index 713728e..d2a8d92 100644
--- a/Java/Backpack.java
+++ b/Java/Backpack.java
@@ -1,29 +1,38 @@
-记得这个DP。
-row是item大小: 0, A[0], A[1] ... A[A.length -1]
-col是背包累积的size: 0, 1, 2, ... m.
+M
+
+DP。
+ row是item大小: 0, A[0], A[1] ... A[A.length -1]
+ col是背包累积的size: 0, 1, 2, ... m.
+
+想法:
+ dp[i][j]有这么i-1个item, 用他们可否组成size为j的背包?true/false. (反过来考虑了,不是想是否超过size j, 而是考虑是否能拼出exact size == j)。
+ 注意注意:虽然dp里面一直存在i的位置,实际上考虑的是在i位置的时候,看前i-1个item.
-想法是这样:
-dp[i][j]有这么i-1个item, 用他们可否组成size为j的背包?true/false. (反过来考虑了,不是想是否超过size j, 而是考虑是否能拼出exact size == j)。
-注意注意:虽然dp里面一直存在i的位置,实际上考虑的是在i位置的时候,看前i-1个item.
看一遍code,会发现:
- 1. picked A[i-1] 如果上一个item, A[i-1]被加了上来, 用j-A[i-1]看看,是否这再前一步也true. true就好啦!
- 2. did not pick A[i-1]. 那就是说,不加上A[i-1], 上一行d[i-1][j]还是需要是true。
+ 1. picked A[i-1]: 如果上一个item, A[i-1],被加了上来, 用j-A[i-1]看看,是否这再前一步也true. true就好啦。
+ 2. did not pick A[i-1]: 那就是说,不加上A[i-1], 上一行d[i-1][j]还是需要是true。
+
+最后:
+ 跑一边dp 最下面一个row. 从末尾开始找,最末尾的一个j (能让dp[i][j] == true)的,就是最多能装的大小 :)
+
+时间,空间都是:O(mn)
-最后:
-跑一边dp 最下面一个row. 从末尾开始找,最末尾的一个j (能让dp[i][j] == true)的,就是最多能装的大小 :)
+再有:
+O(m)时间的做法,具体看solution. 注意j是倒序的啊!
+依然是O(mn)的空间
-再有:
-O(m)的做法,注意j是倒序的啊!
```
/*
Given n items with size Ai, an integer m denotes the size of a backpack.
How full you can fill this backpack?
Example
-If we have 4 items with size [2, 3, 5, 7], the backpack size is 11, we can select [2, 3, 5], so that the max size we can fill this backpack is 10. If the backpack size is 12. we can select [2, 3, 7] so that we can fulfill the backpack.
+If we have 4 items with size [2, 3, 5, 7], the backpack size is 11, we can select [2, 3, 5],
+so that the max size we can fill this backpack is 10.
+If the backpack size is 12. we can select [2, 3, 7] so that we can fulfill the backpack.
You function should return the max size we can fill in the given backpack.
@@ -45,8 +54,8 @@
Thoughts: Recap on 12.02.2015
State
DP[i][j]: i is the index of Ai, and j is the size from (0 ~ m).
- It means: depending if we added A[i-1], can we add up to j-space?Return ture/false.
- Note: that is, even j == 0, and I have a item with size == 2, I can still choose not to add, which means the backpack can reach j ==0. True.
+ It means: depending if we added A[i-1], can we full-fill j-space? Return ture/false.
+ Note: that is, even j == 0, and I have a item with size == 0. There is nothing to add, which means the backpack can reach j == 0. True.
However, if we have a item with size == 2, but I need to fill space == 1.
I will either pick/not pick item of size 2; either way, can't fill a backpack with size 1. False;
Function:
@@ -68,16 +77,16 @@ public int backPack(int m, int[] A) {
for (int i = 1; i <= A.length; i++) {
for (int j = 0; j <= m; j++) {
- //added A[i - 1]
+ //j is large enough:
if (j - A[i - 1] >= 0) {
+ //not added A[i - 1] or added A[i - 1]
dp[i][j] = dp[i - 1][j] || dp[i - 1][j - A[i - 1]];
- } else {
- //not added A[i - 1];
+ } else {// j not large enough, ofcourse not adding A[i-1]
dp[i][j] = dp[i - 1][j];
}
}
}
-
+ //Largest possible size with dp[j] == true
for (int j = m; j >= 0; j--) {
if (dp[A.length][j]) {
return j;
@@ -89,53 +98,6 @@ public int backPack(int m, int[] A) {
-/*
-Thoughts:
-Well, I kind of forgot about how we did this in algorithm class, but here we go, after a bit research:
-DP[i][j] means: if i number of items in A, can we fill the bag size of j? Then, save a boolean in DP[i][j]. That means, if i items are too much for j?
-
-So, there are two cases:
-1. A[i] is unfortunately too big to fit into size j, so skip item A[i] and use DP[i-1][j].
-2. OR, the other case: A[i] fits in well. We realize 2 things:
- a. first (i-1)th items much fit in well into the bag size of (j - A[i - 1]): DP[i-1][j - A[i-1]]. Basically says items must be fit in (true) before adding A[i]
- b. AND (j - A[i - 1]) must >= 0 to have space for next item i.
-
-End:
-Iterate through j:(m ~ 0), and return j, if DP[A.length][j] is true. We are starting from m, because we need the largest number j.
-
-This is 2D array version: memory mxn, space mxn
-
-*/
-
-public class Solution {
- /**
- * @param m: An integer m denotes the size of a backpack
- * @param A: Given n items with size A[i]
- * @return: The maximum size
- */
- public int backPack(int m, int[] A) {
- if (A == null || m == 0) {
- return 0;
- }
-
- boolean[][] DP = new boolean[A.length + 1][m + 1];
- DP[0][0] = true;
- for (int i = 1; i <= A.length; i++) {
- for (int j = 0; j <= m; j++) {
- DP[i][j] = DP[i - 1][j] || (j - A[i - 1] >= 0 && DP[i - 1][j - A[i - 1]]);
- }
- }
-
- for (int j = m; j >= 0; j--) {
- if (DP[A.length][j]) {
- return j;
- }
- }
- return 0;
- }
-}
-
-
/*
1D array: memory mxn, space m. Tricky tho ...
diff --git a/Java/Balanced Binary Tree.java b/Java/Balanced Binary Tree.java
old mode 100644
new mode 100755
index 076d297..8c0f24a
--- a/Java/Balanced Binary Tree.java
+++ b/Java/Balanced Binary Tree.java
@@ -1,17 +1,18 @@
+M
+
1. DFS using depth marker: 每个depth都存一下。然后如果有不符合条件的,存为-1.
- 一旦有-1, 就全部返回。
- 最后比较返回结果是不是-1. 是-1,那就false
+ 一旦有-1, 就全部返回。
+ 最后比较返回结果是不是-1. 是-1,那就false.
+ Traverse 整个tree, O(n)
-2. 从基本的题目理解考虑,想到leaf node的情况。如果判断了leaf node, 那其他node应该就是可以recursive。
- 直接在isBalanced上面recursive.
- 然后这个可能是个小小的优化,因为不需要计算所有的depth.一旦发现一个false,其他的就不需要计算,直接返回了。
+2. Only calculate depth using maxDepth function. Same concept as in 1, but cost more traversal efforts.
```
/*
-46% Accepted
Given a binary tree, determine if it is height-balanced.
-For this problem, a height-balanced binary tree is defined as a binary tree in which the depth of the two subtrees of every node never differ by more than 1.
+For this problem, a height-balanced binary tree is defined as a binary tree,
+in which the depth of the two subtrees of every node never differ by more than 1.
Example
Given binary tree A={3,9,20,#,#,15,7}, B={3,#,20,15,7}
@@ -24,7 +25,7 @@
The binary tree A is a height-balanced binary tree, but B is not.
Tags Expand
-Tree Depth First Search
+Binary Search Divide and Conquer Recursion
*/
@@ -41,49 +42,6 @@
*/
-/*
- 12.11.2015
- Recap:
- The original way of marking depth and -1 is good. However, that has to traverse entire tree.
-
- Today, let's think about the leaf case, and see if we can directly recurse on isBalanced itself.
- leaf case:
- root == null, return true;
- left = root.left; right = root.right;
- left == null && right == null : true;
-
- left == null && right != null && (right.left != null || right.right != null) {
- false;
- }
-
- need to isBalance(left) && isBalance(right).
-*/
-
-public class Solution {
- /**
- * @param root: The root of binary tree.
- * @return: True if this Binary tree is Balanced, or false.
- */
- public boolean isBalanced(TreeNode root) {
- if (root == null || (root.left == null && root.right == null)) {
- return true;
- }
-
- TreeNode left = root.left;
- TreeNode right = root.right;
- //One of left or right is null.
- if (left == null && (right.left != null || right.right != null)) {
- return false;
- }
- if (right == null && (left.left != null || left.right != null)) {
- return false;
- }
- //none of left or right is null
- return isBalanced(left) && isBalanced(right);
- }
-}
-
-
/*
Thinking process:
@@ -94,31 +52,90 @@ same process as maxDepth() method.
at the top return, check if -1.
*/
-public class Solution {
- /**
- * @param root: The root of binary tree.
- * @return: True if this Binary tree is Balanced, or false.
- */
+/* 3.3.2016 recap:
+ Recursive 1:
+ Use helper to calculate depth, and also check if left/right depth differ by 1. If all good, return actual depth
+*/
+
+ public class Solution {
public boolean isBalanced(TreeNode root) {
- return maxDepth(root) != -1;
+ if (root == null) {
+ return true;
+ }
+ return helper(root) > 0;
}
- public int maxDepth(TreeNode root) {
- if (root == null) {
+ public int helper(TreeNode node) {
+ if (node == null) {
return 0;
}
+ int leftDepth = helper(node.left);
+ int rightDepth = helper(node.right);
- int left = maxDepth(root.left);
- int right = maxDepth(root.right);
+ if (leftDepth < 0 || rightDepth < 0 || Math.abs(leftDepth - rightDepth) > 1) {
+ return Integer.MIN_VALUE;
+ }
- if (Math.abs(left - right) > 1 || left == -1 || right == -1) {
- return -1;
+ return Math.max(leftDepth, rightDepth) + 1;
+ }
+}
+
+
+/*
+ Recursive 2:
+ Calculate a node's maxDepth. Compare a parent node's sub tree for maxDepth
+*/
+public class Solution {
+ public boolean isBalanced(TreeNode root) {
+ if (root == null) {
+ return true;
}
+ int leftDepth = maxDepth(root.left);
+ int rightDepth = maxDepth(root.right);
- return Math.max(left, right) + 1;
+ if (Math.abs(leftDepth - rightDepth) > 1) {
+ return false;
+ }
+ return isBalanced(root.left) && isBalanced(root.right);
+ }
+
+ public int maxDepth(TreeNode node) {
+ if (node == null) {
+ return 0;
+ }
+ return Math.max(maxDepth(node.left), maxDepth(node.right)) + 1;
}
}
+
+/*
+ Failed Solution:
+ check cases:
+ root == null, return true;
+ left = root.left; right = root.right;
+ left == null && right == null : true;
+ left == null && right != null && (right.left != null || right.right != null) {
+ false;
+ }
+ return isBalance(left) && isBalance(right).
+
+ failed case:[1,2,2,3,3,null,null,4,4]
+ 1
+ 2 2
+ 3 3
+ 4 4
+Previous notes:
+2. 从基本的题目理解考虑,想到leaf node的情况。如果判断了leaf node, 那其他node应该就是可以recursive。
+ 直接在isBalanced上面recursive.
+ 关键return false的判断情况:如果有个node是null, 那么同一行相邻的那个,一旦有了children,那么就说明两个分支的depth已经是>=2了,那么就return false.
+
+ 然后这个可能是个小小的优化,因为不需要计算所有的depth.一旦发现一个false,其他的就不需要计算,直接返回了。
+
+
+
+*/
+
+
```
\ No newline at end of file
diff --git a/Java/Best Time to Buy and Sell Stock I.java b/Java/Best Time to Buy and Sell Stock I.java
index a71506f..f33f2dd 100644
--- a/Java/Best Time to Buy and Sell Stock I.java
+++ b/Java/Best Time to Buy and Sell Stock I.java
@@ -1,24 +1,37 @@
-n天就买卖一次。
-每天都算算目前最小值Min是多少。O(n)
-每天都算算和当下的Min买卖,profit最大多少。
+M
+
+理解意思是关键:
+ 每天都就交易价格,n天只让买卖一次,那就找个最低价买进,找个最高价卖出。
+ 记录每天最小值Min是多少。O(n)
+ 每天都算和当下的Min买卖,profit最大多少。
+
+
```
/*
Say you have an array for which the ith element is the price of a given stock on day i.
-If you were only permitted to complete at most one transaction (ie, buy one and sell one share of the stock), design an algorithm to find the maximum profit.
+If you were only permitted to complete at most one transaction (ie, buy one and sell one share of the stock),
+design an algorithm to find the maximum profit.
+Have you met this question in a real interview? Yes
Example
+Given an example [3,2,3,1,2], return 1
+
Tags Expand
-Array Dynamic Programming
+Greedy Enumeration Array Facebook Uber
+
+*/
+
+/*
-Thinking process:
+Thoughts
First to understand what this question is asking:
Each element is a price of the same stock on that specific day. Of course we want to buy in with min-price and sell out with max-price.
Find the min-price by looping through the array.
Find the max-profit: price[i] - min-price, which requires a loop through the loop again.
We put above 2 tasks into one-pass for loop
-*/
+*/
public class Solution {
/**
* @param prices: Given an integer array
diff --git a/Java/Best Time to Buy and Sell Stock II.java b/Java/Best Time to Buy and Sell Stock II.java
index 90196d9..2ca5b6c 100644
--- a/Java/Best Time to Buy and Sell Stock II.java
+++ b/Java/Best Time to Buy and Sell Stock II.java
@@ -1,16 +1,34 @@
-找涨幅最大的区间,买卖。
-飞似得涨,到峰顶,就卖。
+M
+
+和Stock I 的区别:可以买卖多次,求总和的最大盈利。
+
+找涨幅最大的区间,买卖:
+找到低谷,买进:peek = start + 1 时候,就是每次往前走一步;若没有上涨趋势,继续往低谷前进。
+涨到峰顶,卖出:一旦有上涨趋势,进一个while loop,涨到底, 再加个profit.
+
+中间的:
+ profit += prices[peek - 1] - prices[start]; 听特别的。
+ 当没有上涨趋势时候,peek-1也就是start, 所以这里刚好profit += 0.
+
+O(n)
+
```
/*
Say you have an array for which the ith element is the price of a given stock on day i.
-Design an algorithm to find the maximum profit. You may complete as many transactions as you like (ie, buy one and sell one share of the stock multiple times). However, you may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again).
+Design an algorithm to find the maximum profit. You may complete as many transactions as you like
+(ie, buy one and sell one share of the stock multiple times). However, you may not engage in multiple transactions
+at the same time (ie, you must sell the stock before you buy again).
Example
+Given an example [2,1,2,0,1], return 2
+
Tags Expand
-Greedy Array
+Greedy Enumeration Array
+*/
-Thinking process:
+/*
+Thought:
In this case, since we know the entire stock price for all days in the array, we want to this:
Sell it at nearest peek price and buy it on the next dropped price, then sell again at next peek.
Two pointers, start and peek, to track the starting point and the peek.
@@ -19,9 +37,10 @@ Design an algorithm to find the maximum profit. You may complete as many transac
Inner while loop that finds the peek from start.
Note: peek always has index >= start+1.
Sum up all profit and return it.
-Tricky thing: we are looking for max profit, but does not require to sell the stock by end of array. So if the price is dropping, we are not selling and we are not losing/winning anything.
-*/
+Tricky thing: we are looking for max profit, but does not require to sell the stock by end of array.
+So if the price is dropping, we are not selling and we are not losing/winning anything.
+*/
class Solution {
/**
* @param prices: Given an integer array
diff --git a/Java/Best Time to Buy and Sell Stock III .java b/Java/Best Time to Buy and Sell Stock III .java
index 90a42f1..699e1d2 100644
--- a/Java/Best Time to Buy and Sell Stock III .java
+++ b/Java/Best Time to Buy and Sell Stock III .java
@@ -1,29 +1,42 @@
-两次卖出机会。那反正就是:找峰头;然后往下再找一个峰头。
-怎么样在才能Optimize呢。
-从两边同时开始找Max.
-leftProfit是从左往右,每个i点上的最大Profit。
-rightProfit是从i点开始到结尾,每个点上的最大profit.
-那么把左右两边在i上,两边相加的最大值找到就可以了。
+M
+
+比stock II 多了一个限制:只有2次卖出机会。也就是:找峰头;然后往下再找一个峰头。
+
+怎么样在才能Optimize两次巅峰呢?
+
+从两边同时开始找Max!(棒棒的想法)
+
+ leftProfit是从左往右,每个i点上的最大Profit。
+ rightProfit是从i点开始到结尾,每个点上的最大profit.
+ 那么在i点上,就是leftProfit,和右边rightProfit的分割点。在i点,leftProfit+rightProfit相加,找最大值。
+
+三个O(n),还是O(n)
+
```
/*
Say you have an array for which the ith element is the price of a given stock on day i.
Design an algorithm to find the maximum profit. You may complete at most two transactions.
+Example
+Given an example [4,4,6,1,1,4,2,5], return 6.
+
Note
You may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again).
-Example
Tags Expand
-Array Dynamic Programming
+Enumeration Forward-Backward Traversal Array
+
+*/
-Thinking process:
+/*
+Thoughts:
Idea from NineChapter: use two arrays to mark max values, however the max values are calculated from left/right sides.
Left[] marks max profit value in the range from a left-index to current index. Tracking left-min.
Right[] marks max profit value in the range from current index to a right-index. Tracking right-max.
If looking at right[i] and left[i] together at index i, they are always representing left-max-profit value and right-max-profit value. Add them together and get results.
-*/
+*/
class Solution {
/**
* @param prices: Given an integer array
@@ -57,11 +70,4 @@ public int maxProfit(int[] prices) {
-
-
-
-
-
-
-
```
\ No newline at end of file
diff --git a/Java/Best Time to Buy and Sell Stock IV.java b/Java/Best Time to Buy and Sell Stock IV.java
index 56aba94..4979ca2 100644
--- a/Java/Best Time to Buy and Sell Stock IV.java
+++ b/Java/Best Time to Buy and Sell Stock IV.java
@@ -1,6 +1,28 @@
-有问题。还不是非常理解:
-best time to buy and sell stock: 为什么 i-1天的卖了又买,可以和第 i 天的卖合成一次交易?
-因为每天交易的price是定的。所以卖了又买,等于没卖!这就是可以合并的原因。要对价格敏感啊少年。
+H
+
+记得要理解: 为什么 i-1天的卖了又买,可以和第 i 天的卖合成一次交易?
+ 因为每天交易的price是定的。所以卖了又买,等于没卖!这就是可以合并的原因。要对价格敏感啊少年。
+
+Inspired from here:
+http://liangjiabin.com/blog/2015/04/leetcode-best-time-to-buy-and-sell-stock.html
+
+局部最优解 vs. 全局最优解:
+ local[i][j] = max(global[i – 1][j – 1] + diff, local[i – 1][j] + diff)
+ global[i][j] = max(global[i – 1][j], local[i][j])
+
+local[i][j]: 第i天,当天一定进行第j次交易的profit
+global[i][j]: 第i天,总共进行了j次交易的profit.
+
+local[i][j]和global[i][j]的区别是:local[i][j]意味着在第i天一定有交易(卖出)发生。
+ 当第i天的价格高于第i-1天(即diff > 0)时,那么可以把这次交易(第i-1天买入第i天卖出)跟第i-1天的交易(卖出)合并为一次交易,即local[i][j]=local[i-1][j]+diff;
+ 当第i天的价格不高于第i-1天(即diff<=0)时,那么local[i][j]=global[i-1][j-1]+diff,而由于diff<=0,所以可写成local[i][j]=global[i-1][j-1]。
+ (Note:在我下面这个solution里面没有省去 +diff)
+
+global[i][j]就是我们所求的前i天最多进行k次交易的最大收益,可分为两种情况:
+ 如果第i天没有交易(卖出),那么global[i][j]=global[i-1][j];
+ 如果第i天有交易(卖出),那么global[i][j]=local[i][j]。
+
+
```
/*
@@ -29,11 +51,6 @@
*/
class Solution {
- /**
- * @param k: An integer
- * @param prices: Given an integer array
- * @return: Maximum profit
- */
public int maxProfit(int k, int[] prices) {
if (prices == null || prices.length < 2 || k <= 0) {
return 0;
diff --git a/Java/Binary Representation.java b/Java/Binary Representation.java
index 3db457d..188d5e6 100644
--- a/Java/Binary Representation.java
+++ b/Java/Binary Representation.java
@@ -1,19 +1,23 @@
-主要就是要分两半。
+H
-Integer那一半好弄,Loop里面 num%2, num/2就好。
-Decimal那边复杂点,bit == 1的数学条件是:
-当下num * 2 - 1 >= 0...
-然后循环时候还要 num * 2 - 1, 或者 num * 2
+首先要分两半解决,断点是'.': str.split("\\.");
-因为num是 double, 小于0的小数,所以其实这样做下去很可能无限循环。
+Integer那一半好弄,whie loop里: num%2, num/2。
-所以题目也才有了32BIT的要求!
+Decimal那边复杂点.
+ bit == 1的数学条件:当下num * 2 >= 1。 更新: num = num * 2 - 1;
+ bit == 0的数学条件: num * 2 < 1. 更新: num = num * 2
+
+注意:num是 double, 小数在 (num = num * 2 -1)的公式下可能无限循环. 因此check: num重复性,以及binary code < 32 bit.
+
+(所以题目也才有了32BIT的要求!)
```
/*
-Given a (decimal - e.g. 3.72) number that is passed in as a string, return the binary representation that is passed in as a string. If the fractional part of the number can not be represented accurately in binary with at most 32 characters, return ERROR.
+Given a (decimal - e.g. 3.72) number that is passed in as a string,
+return the binary representation that is passed in as a string.
+If the fractional part of the number can not be represented accurately in binary with at most 32 characters, return ERROR.
-Have you met this question in a real interview? Yes
Example
For n = "3.72", return "ERROR".
@@ -44,10 +48,6 @@ Given a (decimal - e.g. 3.72) number that is passed in as a string, return the b
*/
public class Solution {
- /**
- *@param n: Given a decimal number that is passed in as a string
- *@return: A string
- */
public String binaryRepresentation(String n) {
if (n.length() == 0 || n.equals("0")) {
return "0";
diff --git a/Java/Binary Search Tree Iterator.java b/Java/Binary Search Tree Iterator.java
old mode 100644
new mode 100755
index 0333f5a..c76ad88
--- a/Java/Binary Search Tree Iterator.java
+++ b/Java/Binary Search Tree Iterator.java
@@ -1,17 +1,41 @@
-理解binary search tree inorder traversal的规律。
-都是先找left.left.left ....left. 为top。
-然后再找parent,然后再right.
+H
+
+用O(h)空间的做法:
+
+理解binary search tree inorder traversal的规律:
+ 先找left.left.left ....left 到底,这里是加进stack.
+ 然后考虑parent,然后再right.
+
+例如这题:
+ stack里面top,也就是tree最左下角的node先考虑,取名rst.
+ 其实这个rst拿出来以后, 它也同时是最底层left null的parent,算考虑过了最底层的parent。
+ 最后就考虑最底层的parent.right, 也就是rst.right.
+
+注意:
+ next()其实有个while loop, 很可能是O(h).题目要求average O(1),所以也是okay的.
+
+
+用O(1)空间的做法:不存stack, 时刻update current为最小值。
+
+找下一个最小值,如果current有right child:
+ 和用stack时的iteration类似,那么再找一遍current.right的left-most child,就是最小值了。
+
+如果current没有right child:
+ 那么就要找current node的右上parent, search in BinarySearchTree from root.
+
+注意:
+ 一定要确保找到的parent满足parent.left == current.
+ 反而言之,如果current是parent的 right child, 那么下一轮就会重新process parent。
+ 但是有错:binary search tree里面parent是小于right child的,也就是在之前一步肯定visit过,如此便会死循环。
+
-这个题目里面找到rst之后,首先考虑这个rst.right
- 其实rst在这里虽然是most left node, 但对于rst.right来说,其实它也是parent.
-所以每次把left全部弄一边的时候,parent node其实也都是顾及到了的。
```
/*
Design an iterator over a binary search tree with the following rules:
Elements are visited in ascending order (i.e. an in-order traversal)
next() and hasNext() queries run in O(1) time in average.
-Have you met this question in a real interview? Yes
+
Example
For the following binary search tree, in-order traversal by using iterator is [1, 6, 10, 11, 12]
@@ -29,14 +53,7 @@ Extra memory usage O(h), h is the height of the tree.
Binary Tree LintCode Copyright Non Recursion Binary Search Tree Google LinkedIn Facebook
*/
-/*
- Thoughts://http://blog.csdn.net/u014748614/article/details/46800891
- Put all left nodes into stack. Then top of stack must be the first element in in-order-traversal.
- We never add right node into stack directly, but ever time before returnning the rst node, we take care of rst.right right away.
- That is, find next() when rst.right as root.
- very smart use of a 'currnt' node.
- It's like a pointer on the tree, but only operates when that current node is not null, and under condition of having left child.
-*/
+
/**
* Definition of TreeNode:
@@ -55,6 +72,58 @@ That is, find next() when rst.right as root.
* do something for node
* }
*/
+
+//Recap 02.24.2016: Similar to solution below. O(h) space.
+//Stack, inorder traversal; first add left node till end. Each next() trigger a iteration.
+public class BSTIterator {
+ public Stack stack = new Stack();
+
+ //@param root: The root of binary tree.
+ //Add till end of left
+ public BSTIterator(TreeNode root) {
+ if (root == null) {
+ return;
+ }
+ stack.push(root);
+ while (root.left != null) {
+ stack.push(root.left);
+ root = root.left;
+ }
+ }
+
+ //@return: True if there has next node, or false
+ public boolean hasNext() {
+ return stack.size() > 0;
+ }
+
+ //@return: return next node
+ public TreeNode next() {
+ TreeNode node = stack.pop();
+ if (node.right != null) {
+ TreeNode temp = node.right;
+ stack.push(temp);
+ while (temp.left != null) {
+ stack.push(temp.left);
+ temp = temp.left;
+ }
+ }
+ return node;
+ }
+}
+
+
+
+/*
+ Previous correct implementation, O(h) space.
+ Thoughts:http://blog.csdn.net/u014748614/article/details/46800891
+ Put all left nodes into stack. Then top of stack must be the first element in in-order-traversal.
+ We never add right node into stack directly, but ever time before returnning the rst node, we take care of rst.right right away.
+ That is, find next() when rst.right as root.
+ very smart use of a 'currnt' node.
+ It's like a pointer on the tree, but only operates when that current node is not null, and under condition of having left child.
+
+*/
+
public class BSTIterator {
public Stack stack = new Stack();
public TreeNode current;
@@ -80,13 +149,95 @@ public TreeNode next() {
}
}
+/*
+ Use O(1) space, which means we will not use O(h) stack.
+
+ To begin:
+ 1. hasNext()? current.val <= endNode.val to check if the tree is fully traversed.
+
+ 2. Find min via left-most: We can alwasy look for left-most to find next minimum value.
+
+ 3. Once left-most min is checked (name it `current`). Next min will be 2 cases:
+ If current.right != null, we can keep looking for current.right's left-most child, as next min.
+ Or, we need to look backwards for parent. Use binary search tree to find current's parent node.
+
+ Note: when doing binary search for parent, make sure it satisfies parent.left = current.
+
+ Because:If parent.right == current, that parent must has been visited before. In binary search tree,
+ we know that parent.val < parent.right.val. We need to skip this special case, since it leads
+ to ifinite loop.
+
+*/
+
+
+public class BSTIterator {
+ public TreeNode root;
+ public TreeNode current;
+ public TreeNode endNode;
+ //@param root: The root of binary tree.
+ public BSTIterator(TreeNode root) {
+ if (root == null) {
+ return;
+ }
+ this.root = root;
+ this.current = root;
+ this.endNode = root;
+
+ while (endNode != null && endNode.right != null) {
+ endNode = endNode.right;
+ }
+ while (current != null && current.left != null) {
+ current = current.left;
+ }
+ }
+ //@return: True if there has next node, or false
+ public boolean hasNext() {
+ return current != null && current.val <= endNode.val;
+ }
+
+ //@return: return next node
+ public TreeNode next() {
+ TreeNode rst = current;
+ //current node has right child
+ if (current.right != null) {
+ current = current.right;
+ while (current.left != null) {
+ current = current.left;
+ }
+ } else {//Current node does not have right child.
+ current = findParent();
+ }
+ return rst;
+ }
+
+ //Find current's parent, where parent.left == current.
+ public TreeNode findParent(){
+ TreeNode node = root;
+ TreeNode parent = null;
+ int val = current.val;
+ if (val == endNode.val) {
+ return null;
+ }
+ while (node != null) {
+ if (val < node.val) {
+ parent = node;
+ node = node.left;
+ } else if (val > node.val) {
+ node = node.right;
+ } else {//node.val == current.val
+ break;
+ }
+ }
+ return parent;
+ }
+}
+```
-```
\ No newline at end of file
diff --git a/Java/Binary Search.java b/Java/Binary Search.java
deleted file mode 100644
index 5931e4a..0000000
--- a/Java/Binary Search.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
-Easy Binary Search Show Result My Submissions
-
-26% Accepted
-Binary search is a famous question in algorithm.
-
-For a given sorted array (ascending order) and a target number, find the first index of this number in O(log n) time complexity.
-
-If the target number does not exist in the array, return -1.
-
-Example
-If the array is [1, 2, 3, 3, 4, 5, 10], for given target 3, return 2.
-
-Challenge
-If the count of numbers is bigger than MAXINT, can your code work properly?
-
-Tags Expand
-Binary Search
-
--
-*/
-
-class Solution {
- /**
- * @param nums: The integer array.
- * @param target: Target to find.
- * @return: The first position of target. Position starts from 0.
- */
- public int binarySearch(int[] nums, int target) {
- //write your code here
- if (nums.length == 0) {
- return -1;
- }
-
- int start = 0;
- int end = nums.length - 1;
- int mid;
-
- while (start + 1 < end) {
- mid = start + (end - start) / 2;
- if (nums[mid] < target) {
- start = mid;
- } else if (nums[mid] > target) {
- end = mid;
- } else {
- end = mid;
- }
- }
-
- if (nums[start] == target) {
- return start;
- } else if (nums[end] == target) {
- return end;
- } else {
- return -1;
- }
- }
-
-
-}
-
diff --git a/Java/Binary Tree Inorder Traversal.java b/Java/Binary Tree Inorder Traversal.java
old mode 100644
new mode 100755
index c53c3e8..95fd667
--- a/Java/Binary Tree Inorder Traversal.java
+++ b/Java/Binary Tree Inorder Traversal.java
@@ -1,19 +1,22 @@
-1. Recursive: Divide and Conquer
-2. Stack: add left nodes all the way; then print curr; move to right, add right if possible.
-3. Recursive with helper method
+E
+法一:
+Recursive: Divide and Conquer, with helper(dfs) method
-注意inorder traversal在check right node的事后,
-不论right == null or != null, 每次都要强行move to right.
+法二:
+Stack:
+Add left nodes all the way
+Print curr
+Move to right, add right if possible.
+
+注意stack.pop()在加完left-most child 的后,一定要curr = curr.right.
-如果不node = node.right,
-很可能发生窘境:
-node alays = stack.top(), 然后stack.top()一直是一开始把left 全部遍历的内容。所以就会infinite loop, 永远在左边上下上下。
+若不右移,很可能发生窘境:
+curr下一轮还是去找自己的left-most child,不断重复curr and curr.left, 会infinite loop, 永远在左边上下上下。
```
/*
-Binary Tree Inorder Traversal
Given a binary tree, return the inorder traversal of its nodes' values.
Example
@@ -32,12 +35,76 @@
Can you do it without recursion?
Tags Expand
-Binary Tree
+Recursion Binary Tree Binary Tree Traversal
*/
/*
- 3. Use a helper method, recursively add to rst
+ recap 3.15.2016
+ Recursive
+*/
+public class Solution {
+ public List inorderTraversal(TreeNode root) {
+ List rst = new ArrayList();
+ if (root == null) {
+ return rst;
+ }
+ dfs(rst, root);
+ return rst;
+ }
+
+ public void dfs(List rst, TreeNode node) {
+ if (node.left != null) {
+ dfs(rst, node.left);
+ }
+ rst.add(node.val);
+ if (node.right != null) {
+ dfs(rst, node.right);
+ }
+ }
+}
+
+
+
+
+/*
+ recap 3.15.2016
+ Iterative
+ stack: add left till end; consume top, if has right, add right; push right.left till end of right's left node.
+*/
+public class Solution {
+ public List inorderTraversal(TreeNode root) {
+ List rst = new ArrayList();
+ if (root == null) {
+ return rst;
+ }
+ Stack stack = new Stack();
+ TreeNode node = root;
+ //Initialize
+ while (node != null) {
+ stack.push(node);
+ node = node.left;
+ }
+ //iteratively add && process via inorder traversal
+ while (!stack.isEmpty()) {
+ node = stack.pop();
+ rst.add(node.val);
+ if (node.right != null) {//process right, but put right's left children on top of stack
+ node = node.right;
+ while (node != null) {
+ stack.push(node);
+ node = node.left;
+ }
+ }
+
+ }
+ return rst;
+ }
+}
+
+
+/*
+ 1. Use a helper method, recursively add to rst
*/
public class Solution {
@@ -78,10 +145,6 @@ public void helper(ArrayList rst, TreeNode node) {
*/
public class Solution {
- /**
- * @param root: The root of binary tree.
- * @return: Inorder in ArrayList which contains node values.
- */
public ArrayList inorderTraversal(TreeNode root) {
ArrayList rst = new ArrayList();
if (root == null) {
@@ -99,7 +162,7 @@ public ArrayList inorderTraversal(TreeNode root) {
//Pop the top node: the curr node
curr = stack.pop();
rst.add(curr.val);
- //Move to right node, and push to satck if needed
+ //Move to right node, and push to stack if needed
curr = curr.right;
if (curr!= null) {
stack.push(curr);
@@ -110,66 +173,7 @@ public ArrayList inorderTraversal(TreeNode root) {
}
-/*
-Thinking process:
-1. Use recursive function: divide and conquer
- recursive on left
- result.add( current.val)
- recursive on right
-2. Use Stack to do traversal
- while stack not empty {
- stack all left childs
- result.(current.val)
- stack 1 right child
- }
-*/
-public class Solution {
-
- //Recursive - Divide and Conquer
- public ArrayList inorderTraversal(TreeNode root) {
- ArrayList rst = new ArrayList();
- if (root == null) {
- return rst;
- }
- inorderRec(rst, root);
- return rst;
- }
- public void inorderRec(ArrayList rst, TreeNode root) {
- if (root == null) {
- return;
- }
- inorderRec(rst, root.left);
- rst.add(root.val);
- inorderRec(rst, root.right);
- }
- //Traversal using Stack
- public ArrayList inorderTraversal(TreeNode root) {
- ArrayList rst = new ArrayList();
- if (root == null) {
- return rst;
- }
- Stack stack = new Stack();
- TreeNode curr = root;
- stack.push(curr);
- while (!stack.empty()) {
- while (curr != null && curr.left != null) {
- curr = curr.left;
- stack.push(curr);
- }
- curr = stack.pop();
- rst.add(curr.val);
- curr = curr.right;
- if (curr != null) {
- stack.push(curr);
- }
- }
- return rst;
- }
-
-
-
-}
```
\ No newline at end of file
diff --git a/Java/Binary Tree Level Order Traversal II.java b/Java/Binary Tree Level Order Traversal II.java
old mode 100644
new mode 100755
index ae360e1..8380746
--- a/Java/Binary Tree Level Order Traversal II.java
+++ b/Java/Binary Tree Level Order Traversal II.java
@@ -1,5 +1,15 @@
+M
+
+普通BFS,用一个queue,加上一个queue.size()来交替换行.
+
+rst里面add(0,...)每次都add在list开头
+
+
+```
+
/*
-Given a binary tree, return the bottom-up level order traversal of its nodes' values. (ie, from left to right, level by level from leaf to root).
+Given a binary tree, return the bottom-up level order traversal of its nodes' values.
+(ie, from left to right, level by level from leaf to root).
Example
Given binary tree {3,9,20,#,#,15,7},
@@ -19,15 +29,7 @@
[3]
]
Tags Expand
-Tree Search Breadth First Search Queue Binary Tree
-
-
-Thinking Process:
-1. Non-recursive
-similar to Binary Tree Level Order Traversal I, just when adding into the final result, add to the top all the time. Then the first added will be at the bottom: result.add(0, list)
-2. Recursive:
- Similar to Level Traversal I, do a dfs. The difference is: everytime, we use ArrayList> like a stack by doing add(0, newList);
- when populating the levelArrayList, make sure to address the correct corresponding level.
+Queue Binary Tree Binary Tree Traversal Breadth First Search
*/
/**
@@ -43,6 +45,18 @@
*/
+ /*
+
+Thoughts:
+1. Non-recursive
+similar to Binary Tree Level Order Traversal I, just when adding into the final result,
+add to the top all the time. Then the first added will be at the bottom: result.add(0, list)
+2. Recursive:
+ Similar to Level Traversal I, do a dfs. The difference is: everytime, we use ArrayList> like a stack by doing add(0, newList);
+ when populating the levelArrayList, make sure to address the correct corresponding level.
+
+ */
+
public class Solution {
/**
* @param root: The root of binary tree.
@@ -89,3 +103,4 @@ public void dfs(TreeNode root, int level, ArrayList> rst) {
}
}
+```
diff --git a/Java/Binary Tree Level Order Traversal.java b/Java/Binary Tree Level Order Traversal.java
old mode 100644
new mode 100755
index 8cdb741..aa2d884
--- a/Java/Binary Tree Level Order Traversal.java
+++ b/Java/Binary Tree Level Order Traversal.java
@@ -1,9 +1,16 @@
-1. 最普通,Non-recursive: bfs, queue
-2. Recursive with dfs: use a level to track. Add curr into corresponding level; each level > rst.size(), add a new [].
- Note: rst is a ArrayList>, where each level is a arraylist; that is why we can add [] into rst to represent a level.
+M
+
+方法1. 最普通,Non-recursive: BFS, queue, 用个queue.size()来end for loop:换行。
+ 或者用两个queue. 当常规queue empty,把backup queue贴上去。
+
+方法2. Recursive with dfs:
+ 每个level都应该有个ArrayList. 那么用一个int level来查看:是否每一层都有了相应的ArrayList。
+ 如果没有,就加上一层。
+ 之后每次都通过DFS在相应的level上面加数字。
+
+
```
/*
-34% Accepted
Given a binary tree, return the level order traversal of its nodes' values. (ie, from left to right, level by level).
Example
@@ -24,21 +31,13 @@
[15,7]
]
Challenge
-Using only 1 queue to implement it.
+Challenge 1: Using only 1 queue to implement it.
+
+Challenge 2: Use DFS algorithm to do it.
Tags Expand
-Tree Search Breadth First Search Queue Binary Tree
+Queue Binary Tree Breadth First Search Binary Tree Traversal Uber LinkedIn Facebook
-Thinking process:
-1. Non-recursive
-Use queue to withhold the parent.
-Poll one parent, add this parent’s value to arrayList
-Add the children into Arraylist
-jump to next level
-2. Recursive
-use a integer to track levels.
-If at a new level, then create a new ArrayList.
-At each node, add the node to corresponding level-ArrayList
*/
/**
@@ -53,6 +52,21 @@
* }
*/
+/*
+Thoughts:
+1. Non-recursive
+Use queue to withhold the parent.
+Poll one parent, add this parent’s value to arrayList
+Add the children into Arraylist
+jump to next level
+2. Recursive
+use a integer to track levels.
+If at a new level, then create a new ArrayList.
+At each node, add the node to corresponding level-ArrayList
+*/
+
+//Non-recurive Iterative way:
+//Even with while + for nested loop, it's just O(n)
public class Solution {
/**
* @param root: The root of binary tree.
@@ -63,7 +77,7 @@ public ArrayList> levelOrder(TreeNode root) {
if (root == null) {
return result;
}
- /* //Non-recurive Iterative way:
+
//Use a queue to list elements: each row
Queue queue = new LinkedList();
queue.offer(root);
@@ -83,9 +97,58 @@ public ArrayList> levelOrder(TreeNode root) {
}
result.add(list);
}//while
- */
+
+ return result;
+ }
+}
+
+//Another Iterative way: using 2 Queues
+public class Solution {
+ public List> levelOrder(TreeNode root) {
+ List> rst = new ArrayList>();
+ if (root == null) {
+ return rst;
+ }
+ Queue queue = new LinkedList();
+ Queue backQueue = new LinkedList();
+ queue.offer(root);
+ ArrayList list = new ArrayList();
+
+ while (!queue.isEmpty()) {
+ TreeNode node = queue.poll();
+ if (node.left != null) {
+ backQueue.offer(node.left);
+ }
+ if (node.right != null) {
+ backQueue.offer(node.right);
+ }
+ list.add(node.val);
+
+ if (queue.isEmpty()) {
+ rst.add(new ArrayList(list));
+ list = new ArrayList();
+ queue = backQueue;
+ backQueue = new LinkedList();
+ }
+
+ }
+ return rst;
+ }
+}
+
+
+
+//Recursive:
+//Recursive with dfs: use a level to track. Add curr into corresponding level; each level > rst.size(), add a new [].
+//Note: rst is a ArrayList>, where each level is a arraylist; that is why we can add [] into rst to represent a level.
+
+public class Solution {
+ public ArrayList> levelOrder(TreeNode root) {
+ ArrayList> result = new ArrayList>();
+ if (root == null) {
+ return result;
+ }
- //Recursive:
dfs(root, 0, result);
return result;
}
diff --git a/Java/Binary Tree Longest Consecutive Sequence.java b/Java/Binary Tree Longest Consecutive Sequence.java
new file mode 100644
index 0000000..37793fe
--- /dev/null
+++ b/Java/Binary Tree Longest Consecutive Sequence.java
@@ -0,0 +1,129 @@
+M
+
+屌炸天的4行代码。Divide and Conquer
+
+主要想法:
+Recursive用好。首先在这个level比一比,可否成。
+不成的话,另立门户, count = 1。
+然后左右开弓。再把结果拿过来比较一下就好了。
+
+```
+/*
+Given a binary tree, find the length of the longest consecutive sequence path.
+
+The path refers to any sequence of nodes from some starting node to any node in the tree
+along the parent-child connections. The longest consecutive path need to be from parent to child
+(cannot be the reverse).
+
+For example,
+ 1
+ \\
+ 3
+ / \\
+ 2 4
+ \\
+ 5
+Longest consecutive sequence path is 3-4-5, so return 3.
+ 2
+ \\
+ 3
+ /
+ 2
+ /
+ 1
+Longest consecutive sequence path is 2-3,not3-2-1, so return 2.
+
+Tags:Tree
+Similar Problems: (H) Longest Consecutive Sequence
+
+*/
+
+/*
+Attemp2: http://www.cnblogs.com/jcliBlogger/p/4923745.html.
+The original solution has just 4 lines of C++ code. That hurts.
+The concept is very much similar as my attempt1, though the code is more clear with recursive call
+1. pass alone a depth.
+2. if consecutive, depth++; else, start from depth 1
+3. Go deeper on both left, and right; both with new depth: currDepth;
+4. Compare the Max of currDept, left's return, right's return.
+*/
+
+/**
+ * Definition for a binary tree node.
+ * public class TreeNode {
+ * int val;
+ * TreeNode left;
+ * TreeNode right;
+ * TreeNode(int x) { val = x; }
+ * }
+ */
+public class Solution {
+ public int longestConsecutive(TreeNode root) {
+ return recursiveHelper(root, null, 0);
+ }
+
+ public int recursiveHelper(TreeNode curr, TreeNode parent, int depth) {
+ if (curr == null) {
+ return 0;
+ }
+ int currDepth = 0;
+ if (parent != null && parent.val + 1 == curr.val) {
+ currDepth = depth + 1;
+ } else {
+ currDepth = 1;
+ }
+ return Math.max(currDepth, Math.max(recursiveHelper(curr.left, curr, currDepth), recursiveHelper(curr.right, curr, currDepth)));
+ }
+}
+
+
+/*
+Attemp1, failed.
+Thoughts:
+Seems like backtracking: we find the lowest level, then return depth, and add it on parent's record if consectutive.
+always record a max value.
+If node.left != null || node.right != null, if consecutive, node.depth = node.child.depth +1
+If node.left == null && node.right == null, return 1;
+
+
+public class Solution {
+ private int max = Integer.MIN_VALUE;
+ public int longestConsecutive(TreeNode root) {
+ dfsOnNode(root);
+ return max;
+ }
+
+ public int dfsOnNode(TreeNode root) {
+ int depth = 0;
+ int localMax = Integer.MIN_VALUE;
+ if (root == null) {
+ return depth;
+ }
+ if (root.left == null && root.right == null) {//ON:right4,
+ depth++;
+ return depth;
+ }
+ if (root.right != null) {//root.right = 3, right4,
+ int childDepth = longestConsecutive(root.right);//ON: 3, right4
+ if (root.val + 1 == root.right.val) {//3+1=4
+ depth = childDepth + 1;//1+1=2
+ } else {
+ depth = 1;
+ }
+ }
+ localMax = Math.max(localMax, depth);
+ if (root.left != null) {
+ int childDepth = longestConsecutive(root.left);
+ if (root.val + 1 == root.left.val) {
+ depth = childDepth + 1;
+ } else {
+ depth = 1;
+ }
+ }
+ localMax = Math.max(localMax, depth);
+ max = Math.max(max, localMax);
+ return localMax;
+ }
+}
+*/
+```
\ No newline at end of file
diff --git a/Java/Binary Tree Maximum Path Sum II.java b/Java/Binary Tree Maximum Path Sum II.java
index 0dbb7b8..3535f3b 100644
--- a/Java/Binary Tree Maximum Path Sum II.java
+++ b/Java/Binary Tree Maximum Path Sum II.java
@@ -1,7 +1,15 @@
-比Binary Tree Maximum Path Sum I 简单许多.
-因为条件给的更多:at least 1 node + have to start from root => have to have root.
-Single path: either left or right.
-If the path sum < 0, just skip it.
+M
+
+比Binary Tree Maximum Path Sum I 简单许多. 因为条件给的更多:at least 1 node + have to start from root => have to have root.
+
+方法1:
+维持一个global或者recursive里的sum。traversal entire tree via DFS. 简单明了。
+
+
+方法2:
+Single path: either left or right.
+If the path sum < 0, just skip it.
+
```
/*
Binary Tree Maximum Path Sum II
@@ -22,6 +30,29 @@
Binary Tree
*/
+/*
+ 02.20.2016 recap
+ just return integer sum, so just traversal the entier binary tree via dfs
+ dfs: node, sum, return sum
+*/
+public class Solution {
+ public int maxPathSum2(TreeNode root) {
+ if (root == null) {
+ return 0;
+ }
+ return dfs(root, 0);
+ }
+ public int dfs (TreeNode node, int sum) {
+ if (node == null) {
+ return sum;
+ }
+ sum += node.val;
+ return Math.max(sum, Math.max(dfs(node.left, sum),
+ dfs(node.right, sum)));
+ }
+}
+
+
/*
Thoughts: maximum path sum from root, so it must include root, and it will be a single path
from root to some point in the tree.
@@ -29,17 +60,6 @@
'contains at least 1 node' -> at least have root.
However, depending on child is positive or negative, we choose add or no add child
*/
-/**
- * Definition of TreeNode:
- * public class TreeNode {
- * public int val;
- * public TreeNode left, right;
- * public TreeNode(int val) {
- * this.val = val;
- * this.left = this.right = null;
- * }
- * }
- */
public class Solution {
/**
* @param root the root of binary tree.
diff --git a/Java/Binary Tree Maximum Path Sum.java b/Java/Binary Tree Maximum Path Sum.java
index f3ad82e..ade8d5e 100644
--- a/Java/Binary Tree Maximum Path Sum.java
+++ b/Java/Binary Tree Maximum Path Sum.java
@@ -1,37 +1,43 @@
-有点难理解.
-复杂原因是:因为可能有负值啊。不能乱assume正数。
-single path max 的计算是为了给后面的comboMax用的。
-如果single path max小于0,那没有什么加到parent上面的意义,所以就被再次刷为0.
-combo的三种情况:(root可能小于0)1. 只有left, 2。 只有右边。 3. root大于0,那么就left,right,curr全部加起来。
- 情况1和情况2去一个最大值,
- 然后和情况三比较。
- 做了两个Math.max(). 然后就有了这一层的comboMax
-
-
-12.11.2015 recap:
- So totally, 5 conditions:
- (save in single:)
- left + curr.val
- right + curr.val
- (save in combo:)
- left,
- right,
- left + curr.val + right
+M
+
+第一次做有点难理解,复杂原因是:因为可能有负值啊。不能乱assume正数。
+ single path max 的计算是为了给后面的comboMax用的。
+ 如果single path max小于0,那没有什么加到parent上面的意义,所以就被再次刷为0.
+
+combo的三种情况:(root可能小于0)
+ 1. 只有left
+ 2。 只有右边
+ 3. root大于0,那么就left,right,curr全部加起来。
+
+情况1和情况2取一个最大值,然后和情况三比较。做了两个Math.max(). 然后就有了这一层的comboMax
+
+
+12.11.2015 recap:
+ So totally, 5 conditions:
+ (save in single)
+ left + curr.val OR right + curr.val
+ (save in combo:)
+ left, right, OR left + curr.val + right
+
```
/*
-23% Accepted
Given a binary tree, find the maximum path sum.
+
The path may start and end at any node in the tree.
+
+
Example
-Given the below binary tree,
- 1
- / \
- 2 3
-Return 6.
+Given the below binary tree:
+
+ 1
+ / \
+2 3
+return 6.
+
Tags Expand
-Dynamic Programming Tree Depth First Search
+Divide and Conquer Dynamic Programming Recursion
*/
@@ -95,8 +101,9 @@ public PathSumType helper(TreeNode root) {
int singlePathMax = Math.max(left.singlePathMax, right.singlePathMax) + root.val;
singlePathMax = Math.max(singlePathMax, 0);//If less than 0, no need to keep, because it only decrease parent-level max.
- //first comparison: does not include curr node at all(this would be applicable when curr.val < 0, so we take this condition into account)
+ //first comparison: does not include root node at all(this would be applicable when curr.val < 0, so we take this condition into account)
int combinedPathMax = Math.max(left.combinedPathMax, right.combinedPathMax);
+ //second comparison:
combinedPathMax = Math.max(combinedPathMax, left.singlePathMax + right.singlePathMax + root.val);
return new PathSumType(singlePathMax, combinedPathMax);
diff --git a/Java/Binary Tree Path Sum.java b/Java/Binary Tree Path Sum.java
index 9e8bfbc..02a05a7 100644
--- a/Java/Binary Tree Path Sum.java
+++ b/Java/Binary Tree Path Sum.java
@@ -1,6 +1,11 @@
-Binary Tree的一个基本题。
-遍历到底,比较sum vs. target。
-注意divde的情况。起码要把遍历的例子写写。
+E
+
+Binary Tree的一个基本题。
+遍历到底,比较sum vs. target。
+注意divide的情况。要把遍历的例子写写。
+
+LeetCode: Path Sum II
+
```
/*
Given a binary tree, find all paths that sum of the nodes in the path equals to a given number target.
@@ -44,6 +49,40 @@
* }
*/
+/*
+3.1.2016 Recap
+Same approach
+*/
+public class Solution {
+ public List> pathSum(TreeNode root, int sum) {
+ List> rst = new ArrayList>();
+ if (root == null) {
+ return rst;
+ }
+ dfs(rst, new ArrayList(), root, 0, sum);
+
+ return rst;
+ }
+
+ public void dfs(List> rst, ArrayList list, TreeNode node, int add, int sum) {
+ list.add(node.val);
+ if (node.left == null && node.right == null) {
+ if (add + node.val == sum) {
+ rst.add(new ArrayList(list));
+ }
+ return;
+ }
+ if (node.left != null) {
+ dfs(rst, list, node.left, add + node.val, sum);
+ list.remove(list.size() - 1);
+ }
+ if (node.right != null) {
+ dfs(rst, list, node.right, add + node.val, sum);
+ list.remove(list.size() - 1);
+ }
+ }
+}
+
public class Solution {
public List> binaryTreePathSum(TreeNode root, int target) {
List> rst = new ArrayList>();
diff --git a/Java/Binary Tree Paths.java b/Java/Binary Tree Paths.java
index f2e8730..f15a24c 100644
--- a/Java/Binary Tree Paths.java
+++ b/Java/Binary Tree Paths.java
@@ -1,7 +1,13 @@
+E
+
+方法1:
Recursive:分叉。Helper。
-非递归练习了一下
-因为要每次切短list, 所以再加了一个Stack 来存level
+方法2,Iterative:
+ 非递归练习了一下
+ 因为要每次切短list, 所以再加了一个Stack 来存level
+
+
```
/*
Binary Tree Paths
@@ -127,10 +133,6 @@ public List binaryTreePaths(TreeNode root) {
return rst;
}
}
-
-
-
-
/**
* Definition of TreeNode:
* public class TreeNode {
diff --git a/Java/Binary Tree Postorder Traversal.java b/Java/Binary Tree Postorder Traversal.java
old mode 100644
new mode 100755
index 795367c..68ed22d
--- a/Java/Binary Tree Postorder Traversal.java
+++ b/Java/Binary Tree Postorder Traversal.java
@@ -1,9 +1,11 @@
-最prefer 2 stack的做法。特别清楚。
-stack1和stack2合作。
-记得这个做法。。。挺神奇的。
+E
-Divide and Conquer 的方法也非常明了!
+最prefer 2 stack的做法:
+ stack1和stack2合作。倒水。记这个做法。。。挺神奇的。
+Divide and Conquer 的recursive方法也非常明了!
+
+注意,这些binary tree traversal的题目,常常有多个做法:recursive or iterative
```
/*
@@ -63,7 +65,7 @@ public ArrayList postorderTraversal(TreeNode root) {
/*
- 2. Non-recursive, interative
+ 2. Non-recursive, iterative
use 2 stacks: pull water from s1 into s2
in s2, we want: at each level, parentNode at bottom, then rightNode, then leftNode
loop through s2, then we print out leftNode, rightNode, parentNode ... in postOrder.
@@ -132,11 +134,4 @@ public void helper(ArrayListrst, TreeNode node) {
}
-
-
-
-
-
-
-
```
\ No newline at end of file
diff --git a/Java/Binary Tree Preorder Traversal.java b/Java/Binary Tree Preorder Traversal.java
old mode 100644
new mode 100755
index f2cc535..1fb121f
--- a/Java/Binary Tree Preorder Traversal.java
+++ b/Java/Binary Tree Preorder Traversal.java
@@ -1,7 +1,10 @@
-Preorder 写写, stack
-1. Divide and conquer
-2. Stack(NON-recursive) push curr, push right, push left.
-3. recursive with helper method
+E
+
+Preorder 写写, stack
+1. Divide and conquer
+2. Stack(NON-recursive) push curr, push right, push left.
+3. recursive with helper method
+
```
/*
Given a binary tree, return the preorder traversal of its nodes' values.
diff --git a/Java/Binary Tree Right Side View.java b/Java/Binary Tree Right Side View.java
new file mode 100644
index 0000000..a599bbd
--- /dev/null
+++ b/Java/Binary Tree Right Side View.java
@@ -0,0 +1,131 @@
+M
+
+最右:即level traversal每一行的最末尾.
+
+BFS,用queue.size()来出发saving result.
+
+```
+/*
+Given a binary tree, imagine yourself standing on the right side of it,
+return the values of the nodes you can see ordered from top to bottom.
+
+For example:
+Given the following binary tree,
+ 1 <---
+ / \\
+2 3 <---
+ \\ \\
+ 5 4 <---
+You should return [1, 3, 4].
+
+Tags: Tree, Depth-first Search, Breadth-first Search
+Similar Problems: (M) Populating Next Right Pointers in Each Node
+
+*/
+
+/**
+ * Definition for a binary tree node.
+ * public class TreeNode {
+ * int val;
+ * TreeNode left;
+ * TreeNode right;
+ * TreeNode(int x) { val = x; }
+ * }
+ */
+
+/*
+02.09.2016 Revist
+Thoughts:
+BFS: traverse all levels, save to ArrayList, get all nodes at end of level list.
+*/
+
+public class Solution {
+ public List rightSideView(TreeNode root) {
+ List rst = new ArrayList();
+ if (root == null) {
+ return rst;
+ }
+ Queue queue = new LinkedList();
+ queue.offer(root);
+ int size = queue.size();
+ while (!queue.isEmpty()) {
+ TreeNode node = queue.poll();
+ size--;
+ if (node.left != null) {
+ queue.offer(node.left);
+ }
+ if (node.right != null) {
+ queue.offer(node.right);
+ }
+ if (size == 0) {
+ rst.add(node.val);
+ size = queue.size();
+ }
+ }
+
+ return rst;
+ }
+}
+
+
+/*
+
+自己想了这个方法,有可能不是特别efficient.
+一个queue放普通的BFS。
+一个queue放level。
+同时维护一个parent value;维护一个跟着BFS跑的level。
+每个node都有一个lv。一旦lv和正在跑的level不一样,证明lv>level,那么也就是说,刚刚换行拉。parent的值,就是上一行最右边的值。DONE.
+
+
+Thoughts:
+Use 2 queue: one for BFS, one for level. Each node in queue has a corresponding level
+Track level.
+WHen level != levelQ.poll(), that means we are moving to next level, and we should record the previous(parent) node's value.
+*/
+
+public class Solution {
+ public List rightSideView(TreeNode root) {
+ List rst = new ArrayList();
+ if (root == null) {
+ return rst;
+ }
+ Queue q = new LinkedList();
+ Queue levelQ = new LinkedList();
+ q.offer(root);
+ levelQ.offer(1);
+ int level = 1;
+ int parent = root.val;
+ TreeNode node = null;
+
+ while (!q.isEmpty()) {
+ node = q.poll();
+ int lv = levelQ.poll();
+ if (level != lv) {
+ level++;
+ rst.add(parent);
+ }
+ parent = node.val;
+ if (node.left != null) {
+ q.offer(node.left);
+ levelQ.offer(lv + 1);
+ }
+ if (node.right != null) {
+ q.offer(node.right);
+ levelQ.offer(lv + 1);
+ }
+ }//END while
+ rst.add(parent);
+ return rst;
+ }
+}
+
+
+
+
+
+
+
+
+
+
+```
\ No newline at end of file
diff --git a/Java/Binary Tree Serialization.java b/Java/Binary Tree Serialization.java
new file mode 100644
index 0000000..ca94852
--- /dev/null
+++ b/Java/Binary Tree Serialization.java
@@ -0,0 +1,182 @@
+M
+
+方法1: BFS. Non-recursive, using queue. 想法直观。level-order traversal. save到一个string里面就好。
+
+方法2: DFS. Recursive. 需要一点思考。basically divide and conquer. 但是代码相对来说短。
+
+```
+
+/*
+Design an algorithm and write code to serialize and deserialize a binary tree. Writing the tree to a file is called 'serialization' and reading back from the file to reconstruct the exact same binary tree is 'deserialization'.
+
+There is no limit of how you deserialize or serialize a binary tree, you only need to make sure you can serialize a binary tree to a string and deserialize this string to the original structure.
+
+Have you met this question in a real interview? Yes
+Example
+An example of testdata: Binary tree {3,9,20,#,#,15,7}, denote the following structure:
+
+ 3
+ / \
+9 20
+ / \
+ 15 7
+Our data serialization use bfs traversal. This is just for when you got wrong answer and want to debug the input.
+
+You can use other method to do serializaiton and deserialization.
+
+Tags Expand
+Binary Tree Microsoft Yahoo
+
+*/
+
+
+ //BFS. store as string, separated by ','
+//Note: need to record null node as well. but be careful don't push null into queue
+class Solution {
+ /**
+ * This method will be invoked first, you should design your own algorithm
+ * to serialize a binary tree which denote by a root node to a string which
+ * can be easily deserialized by your own "deserialize" method later.
+ */
+ public String serialize(TreeNode root) {
+ String rst = "";
+ if (root == null) {
+ return rst;
+ }
+ Queue queue = new LinkedList();
+ queue.offer(root);
+ int size = 0;
+ while (!queue.isEmpty()) {
+ size = queue.size();
+ for (int i = 0; i < size; i++) {
+ TreeNode node = queue.poll();
+ if (node.val == Integer.MIN_VALUE) {
+ rst += "#,";
+ } else {
+ rst += node.val + ",";
+ TreeNode left = node.left == null ?
+ new TreeNode(Integer.MIN_VALUE) : node.left;
+ queue.offer(left);
+ TreeNode right = node.right == null ?
+ new TreeNode(Integer.MIN_VALUE) : node.right;
+ queue.offer(right);
+ }
+ }
+ }
+ return rst;
+ }
+
+ /**
+ * This method will be invoked second, the argument data is what exactly
+ * you serialized at method "serialize", that means the data is not given by
+ * system, it's given by your own serialize method. So the format of data is
+ * designed by yourself, and deserialize it here as you serialize it in
+ * "serialize" method.
+ */
+ public TreeNode deserialize(String data) {
+ if (data == null || data.length() == 0) {
+ return null;
+ }
+ TreeNode root = new TreeNode(0);
+ root.val = Integer.parseInt(data.substring(0, data.indexOf(",")));
+ data = data.substring(data.indexOf(",") + 1);
+
+ Queue queue = new LinkedList();
+ queue.offer(root);
+ int size = 0;
+ while (!queue.isEmpty()) {
+ size = queue.size();
+ for (int i = 0; i < size; i++) {
+ TreeNode node = queue.poll();
+ String temp = data.substring(0, data.indexOf(","));
+ if (!temp.equals("#")) {
+ node.left = new TreeNode(Integer.parseInt(temp));
+ queue.offer(node.left);
+ }
+ data = data.substring(data.indexOf(",") + 1);
+
+ temp = data.substring(0, data.indexOf(","));
+ if (!temp.equals("#")) {
+ node.right = new TreeNode(Integer.parseInt(temp));
+ queue.offer(node.right);
+ }
+ data = data.substring(data.indexOf(",") + 1);
+ }
+ }
+
+ return root;
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+//DFS approach, recursive
+
+/**
+ * Definition of TreeNode:
+ * public class TreeNode {
+ * public int val;
+ * public TreeNode left, right;
+ * public TreeNode(int val) {
+ * this.val = val;
+ * this.left = this.right = null;
+ * }
+ * }
+ */
+class Solution {
+ /**
+ * This method will be invoked first, you should design your own algorithm
+ * to serialize a binary tree which denote by a root node to a string which
+ * can be easily deserialized by your own "deserialize" method later.
+ */
+ public String serialize(TreeNode root) {
+ if (root == null) {
+ return "#,";
+ }
+ String mid = root.val + ",";
+ String left = serialize(root.left);
+ String right = serialize(root.right);
+ mid += left + right;
+ return mid;
+ }
+
+ private String data = "";
+ /**
+ * This method will be invoked second, the argument data is what exactly
+ * you serialized at method "serialize", that means the data is not given by
+ * system, it's given by your own serialize method. So the format of data is
+ * designed by yourself, and deserialize it here as you serialize it in
+ * "serialize" method.
+ */
+ public TreeNode deserialize(String data) {
+ this.data = data;
+ return desHelper();
+ }
+
+ public TreeNode desHelper() {
+ if (this.data.indexOf("#,") == 0) {
+ this.data = this.data.substring(this.data.indexOf(",") + 1);
+ return null;
+ }
+ String midVal = this.data.substring(0, this.data.indexOf(","));
+ TreeNode mid = new TreeNode(Integer.parseInt(midVal));
+ this.data = this.data.substring(this.data.indexOf(",") + 1);
+ TreeNode left = desHelper();
+ TreeNode right = desHelper();
+ mid.left = left;
+ mid.right = right;
+ return mid;
+ }
+}
+
+
+```
\ No newline at end of file
diff --git a/Java/Binary Tree Zigzag Level Order Traversal.java b/Java/Binary Tree Zigzag Level Order Traversal.java
old mode 100644
new mode 100755
index fda05d8..9110727
--- a/Java/Binary Tree Zigzag Level Order Traversal.java
+++ b/Java/Binary Tree Zigzag Level Order Traversal.java
@@ -1,5 +1,11 @@
-/* 24% Accepted
-Given a binary tree, return the zigzag level order traversal of its nodes' values. (ie, from left to right, then right to left for the next level and alternate between).
+M
+
+简单的level traversal.根据level奇数偶数而add到不同位子.
+
+```
+/*
+Given a binary tree, return the zigzag level order traversal of its nodes' values.
+(ie, from left to right, then right to left for the next level and alternate between).
Example
Given binary tree {3,9,20,#,#,15,7},
@@ -21,11 +27,6 @@
Tags Expand
Tree Search Breadth First Search Queue Binary Tree
-Thinking Process:
-1. realize: queue is no longer can be used. draw a example map to see why.
-Instead, use 2 stacks.
-Because we can only take the top of stack, and we are constantly adding to the top of the stac, so we need 2 stacks. One is the current one, will be empty every time when we finish the level. The other one is nextLevel, which holds next level’s nodes temporarily.
-2. Use a boolean to track if which level it’s running at.
*/
/**
@@ -39,8 +40,60 @@
* }
* }
*/
+
+
+//Recap 02.23.2015. BFS. first level = 0; level % 2 = 1, list.add(0, ...)
+public class Solution {
+ /**
+ * @param root: The root of binary tree.
+ * @return: A list of lists of integer include
+ * the zigzag level order traversal of its nodes' values
+ */
+ public ArrayList> zigzagLevelOrder(TreeNode root) {
+ ArrayList> rst = new ArrayList>();
+ if (root == null) {
+ return rst;
+ }
+
+ int level = 0;
+ int size = 0;
+ Queue queue = new LinkedList();
+ queue.offer(root);
+
+ while (!queue.isEmpty()) {
+ size = queue.size();
+ ArrayList list = new ArrayList();
+ for (int i = 0 ; i < size; i++) {
+ TreeNode node = queue.poll();
+ if (level % 2 == 0) {
+ list.add(node.val);
+ } else {
+ list.add(0, node.val);
+ }
+ if (node.left != null) {
+ queue.offer(node.left);
+ }
+ if (node.right != null) {
+ queue.offer(node.right);
+ }
+ }
+ level++;
+ rst.add(list);
+ }
+
+ return rst;
+
+ }
+}
+ /*
+Thought:
+1. realize: queue is no longer can be used. draw a example map to see why.
+Instead, use 2 stacks.
+Because we can only take the top of stack, and we are constantly adding to the top of the stac, so we need 2 stacks. One is the current one, will be empty every time when we finish the level. The other one is nextLevel, which holds next level’s nodes temporarily.
+2. Use a boolean to track if which level it’s running at.
+ */
public class Solution {
/**
* @param root: The root of binary tree.
@@ -89,3 +142,5 @@ public void addLevel(Stack level, TreeNode node) {
}
}
+
+```
\ No newline at end of file
diff --git a/Java/Building Outline.java b/Java/Building Outline.java
old mode 100644
new mode 100755
index 994b2b6..9c270cb
--- a/Java/Building Outline.java
+++ b/Java/Building Outline.java
@@ -1,6 +1,29 @@
+H
+
+又叫做skyline
+
+看网上的解答做, 思路很漂亮。 (http://codechen.blogspot.com/2015/06/leetcode-skyline-problem.html?_sm_au_=isVmHvFmFs40TWRt)
+
+跟scan line的approach类似:
+1. 把所有点分出来, 每个点有index x, 再加上一个height.
+2. 在这个list上排序,根据index和height(注意用负数标记building start point,这样保证start在end 之前。). 叫做 heightPoints
+3. 在processs时候用max-heap (reversed priorityqueue),在ieteraete heightPoints 来存最大的height . 遇到peek,就是一个合理的解
+ 处理1:因为start,end的height都存在了heightPoints里面,这里就是用来check end of bulding的,然后把height 从queue里面remove.
+ 处理2:重复x 上面的许多height? priorityqueue给了我们最高,这okay了;那么其他的重复点,用一个int prev来mark之前做过的,一旦重复,跳过。
+
+想法非常natural。 大题目,脑子乱。
+看了解答再去想,挺naturally doable的。
+
+```
/*
-Given N buildings in a x-axis,each building is a rectangle and can be represented by a triple (start, end, height),where start is the start position on x-axis, end is the end position on x-axis and height is the height of the building. Buildings may overlap if you see them from far away,find the outline of them。
-An outline can be represented by a triple, (start, end, height), where start is the start position on x-axis of the outline, end is the end position on x-axis and height is the height of the outline.
+LintCode description:
+Given N buildings in a x-axis,each building is a rectangle and can be represented by a triple (start, end, height),
+where start is the start position on x-axis, end is the end position on x-axis and height is the height of the building.
+Buildings may overlap if you see them from far away,find the outline of them。
+An outline can be represented by a triple, (start, end, height),
+where start is the start position on x-axis of the outline,
+end is the end position on x-axis and height is the height of the outline.
+
Example
Given 3 buildings:
[
@@ -19,32 +42,114 @@
Tags Expand
LintCode Copyright Heap
*/
+
+/*LeetCode description
+A city's skyline is the outer contour of the silhouette formed by all the buildings in that city when viewed from a distance. Now suppose you are given the locations and height of all the buildings as shown on a cityscape photo (Figure A), write a program to output the skyline formed by these buildings collectively (Figure B).
+
+ Buildings Skyline Contour
+The geometric information of each building is represented by a triplet of integers [Li, Ri, Hi], where Li and Ri are the x coordinates of the left and right edge of the ith building, respectively, and Hi is its height. It is guaranteed that 0 ≤ Li, Ri ≤ INT_MAX, 0 < Hi ≤ INT_MAX, and Ri - Li > 0. You may assume all buildings are perfect rectangles grounded on an absolutely flat surface at height 0.
+
+For instance, the dimensions of all buildings in Figure A are recorded as: [ [2 9 10], [3 7 15], [5 12 12], [15 20 10], [19 24 8] ] .
+
+The output is a list of "key points" (red dots in Figure B) in the format of [ [x1,y1], [x2, y2], [x3, y3], ... ] that uniquely defines a skyline. A key point is the left endpoint of a horizontal line segment. Note that the last key point, where the rightmost building ends, is merely used to mark the termination of the skyline, and always has zero height. Also, the ground in between any two adjacent buildings should be considered part of the skyline contour.
+
+For instance, the skyline in Figure B should be represented as:[ [2 10], [3 15], [7 12], [12 0], [15 10], [20 8], [24, 0] ].
+
+Notes:
+
+The number of buildings in any input list is guaranteed to be in the range [0, 10000].
+The input list is already sorted in ascending order by the left x position Li.
+The output list must be sorted by the x position.
+There must be no consecutive horizontal lines of equal height in the output skyline. For instance, [...[2 3], [4 5], [7 5], [11 5], [12 7]...] is not acceptable; the three lines of height 5 should be merged into one in the final output as such: [...[2 3], [4 5], [12 7], ...]
+
+Hide Tags Divide and Conquer Binary Indexed Tree Heap Segment Tree
+
+*/
+
/*
-Thoughts:
-Well, based on JiuZhang, http://www.jiuzhang.com/solutions/building-outline/, implement a HashHeap.
-**HashHeap. Super long implementation: http://www.jiuzhang.com/solutions/hash-heap/
+ Thoughts
+ Based idea here:http://codechen.blogspot.com/2015/06/leetcode-skyline-problem.html?_sm_au_=isVmHvFmFs40TWRt
+ Here is the thinking process, 3.15.2016
+
+ The class HeightPoint{int x, int height} is very similar to scan line Point{int x, int flag}. However the usage is a bit different.
+ Sort all of the heightPoints by index && by height.
+ Use nagtive height for start point to make sure start appears before end point, tho they share same height
+ We use an extra priorityQueue to store the height being processed (note, this queue, decending order, max in front)
+ When having a negative height(start point), add into queue
+ At each point, find heightest point (common sense!) and mark it on map: the overlapping point at this index will be skipped because the rest are not high enough.
+ How to process the rest redundant point?
+ Here introduce a 'prev' variable that stores last processed value. If same height appears right before curr, don't add to result; it's added during this continuous line.
+ How to maintain the queue?
+ Once a height > 0 appears, remove that height from queue.
+ OKay, let's break it down:
+ because we sort HeightPoint object by index and height, start height will appear before end height of same building, for sure.
+ So whenever positive height appears, the same bulding must have been marked, so can safely remove the height instance from queue.
+ Well, in HeightPoint object, start height is negative for sorting purpose. When adding into queue, use it's absolute value : )
*/
+public class Solution {
+ public class HeightPoint{
+ int x, height;
+ public HeightPoint(int x, int height) {
+ this.x = x;
+ this.height = height;
+ }
+ }
+ public List getSkyline(int[][] buildings) {
+ List rst = new ArrayList();
+ if (buildings == null || buildings.length == 0 || buildings[0].length == 0) {
+ return rst;
+ }
+ //Init the list sorted by index && height
+ List heightPoints = new ArrayList();
+ for (int i = 0; i < buildings.length; i++) {
+ heightPoints.add(new HeightPoint(buildings[i][0], -buildings[i][2]));
+ heightPoints.add(new HeightPoint(buildings[i][1], buildings[i][2]));
+ }
+ Collections.sort(heightPoints, new Comparator() {
+ public int compare(HeightPoint p1, HeightPoint p2) {
+ if (p1.x == p2.x) {
+ return p1.height - p2.height;
+ } else {
+ return p1.x - p2.x;
+ }
+ }
+ });
+ //Process height points
+ //reversed priorityqueue, becase for same pos x, we always want the highest point
+ PriorityQueue queue = new PriorityQueue(1000, Collections.reverseOrder());
+ queue.offer(0);
+ int prev = queue.peek();
+ for (HeightPoint p : heightPoints) {
+ if (p.height < 0) {
+ queue.offer(-p.height);
+ } else {
+ queue.remove(p.height);
+ }
+ int currPeak = queue.peek();
+ if (currPeak != prev) {
+ rst.add(new int[] {p.x, currPeak});
+ prev = currPeak;
+ }
+ }
-/****
- Attempt1, may not be correct.
- Thoughts:
- PriorityQueue, sort by start.
- 1. Keep track of max height.
- 2. Find max height.
- 3. Poll() queue. Whenever there is a jump(up or down) at current node, close a interval.
- 4. When closing interval, set prev = new node.h
-****/
+ return rst;
+ }
+}
-/**
+
+/*
+Thoughts:
+Well, based on JiuZhang, http://www.jiuzhang.com/solutions/building-outline/, implement a HashHeap.
+**HashHeap. Super long implementation: http://www.jiuzhang.com/solutions/hash-heap/
What is HashHeap Exactly? Document below:
-**/
+*/
class HashHeap {
//Heap is a arraylist, which stores the actaul Integer values. It stores the real data
ArrayList heap;
@@ -227,3 +332,5 @@ void siftdown(int id) {
}
}
}
+
+```
\ No newline at end of file
diff --git a/Java/Burst Balloons.java b/Java/Burst Balloons.java
new file mode 100644
index 0000000..ec05ba9
--- /dev/null
+++ b/Java/Burst Balloons.java
@@ -0,0 +1,121 @@
+其实会做之后挺好想的一个DP。
+dp[i][j] = balloons i~j 之间的sum. 然后找哪个点开始burst? 设为x。
+For loop 所有的点作为x, 去burst。
+每次burst都切成了三份:左边可以recusive 求左边剩下的部分的最大值 + 中间3项相乘 + 右边递归下去求最大值。
+
+
+这个是momorization, 而不纯是DP
+因为recursive了,其实还是搜索,但是memorize了求过的值,节省了Processing
+```
+/*
+Given n balloons, indexed from 0 to n-1. Each balloon is painted with a number on it represented by array nums.
+You are asked to burst all the balloons. If the you burst balloon i you will get nums[left] * nums[i] * nums[right] coins.
+Here left and right are adjacent indices of i. After the burst, the left and right then becomes adjacent.
+
+Find the maximum coins you can collect by bursting the balloons wisely.
+
+Note:
+(1) You may imagine nums[-1] = nums[n] = 1. They are not real therefore you can not burst them.
+(2) 0 ≤ n ≤ 500, 0 ≤ nums[i] ≤ 100
+
+Example:
+
+Given [3, 1, 5, 8]
+
+Return 167
+
+ nums = [3,1,5,8] --> [3,5,8] --> [3,8] --> [8] --> []
+ coins = 3*1*5 + 3*5*8 + 1*3*8 + 1*8*1 = 167
+Credits:
+Special thanks to @peisi for adding this problem and creating all test cases.
+
+Hide Company Tags Google
+Show Tags
+Divide and Conquer Dynamic Programming
+
+
+*/
+
+/*
+ Thoughts: as seen in dicussion. Build DP.
+ State:
+ dp[i][j]: the number of max coins can collect between i and j.
+ For a position x in [i,j], where to burst it? So this goes into a divide and conquer method.
+ Burst at x, track the sum, and record the max into dp[i][j]
+ Function:
+ dp[i][j] = Math.max(dp[i][j], DP(i, x-1) + nums[x-1]*nums[x]*nums[x+1] + DP(x+1, j))
+ Init:
+ create dp[n+2][n+2]. (from 0 to n+1)
+ dp[0][1] = 1;
+ dp[n][n+1] = 1;
+ Return:
+ dp[1][n]
+
+ DP(int i, int j, int[][] dp)
+
+ Need to redo that nums.
+*/
+
+
+public class Solution {
+ int[][] dp;
+ int[] values;
+ public int maxCoins(int[] nums) {
+ if (nums == null || nums.length == 0) {
+ return 0;
+ }
+ int n = nums.length;
+ dp = new int[n + 2][n + 2];
+
+ //Initialize new array
+ values = new int[n + 2];
+ values[0] = values[n + 1] = 1;
+ for (int i = 1; i < n + 1; i++) {
+ values[i] = nums[i - 1];
+ }
+
+ return DP(1, n);
+ }
+
+ public int DP(int i, int j){
+ if (dp[i][j] > 0) {//momorization
+ return dp[i][j];
+ }
+ for (int x = i; x <= j; x++) {
+ dp[i][j] = Math.max(dp[i][j], DP(i, x - 1) + values[i-1]*values[x]*values[j+1] + DP(x + 1, j));
+ }
+ return dp[i][j];
+ }
+}
+
+/*
+ 用了recursive + memorization, 但是也可以用传统的DP,比如:
+ for (int length = 1; length < n; length++) [
+ for (int = 0; i < n-1; i++) {
+ j = i + length;
+ if length == 1:
+ dp[i][j] = A[i] * A[j] + A[i]
+ else:
+ dp[i][j] = max {}
+ }
+ }
+
+*/
+
+
+
+/*
+ My Thought: TOO COMPLEX. Should go with the easy DP approach. Also, using a hashMap to trach all the patterns,
+ this might not be applicable: because as the integer array's length goes up, there will be too many possible
+ combinations to store in hashamp.
+ Burst each balloon, and DFS into each branch, calcualte the sum + each balloon-burst's product.
+ Also, use a HahsMap<"Value combination", max value>. to reduce the # of re-calculation.
+ convert nums into string, and in DFS, we don't even need bakc-tracking
+ helper(list, sum)
+
+
+ Thoughts:http://www.cnblogs.com/grandyang/p/5006441.html
+ dp[i,j]: burst range [i~j]'s max coins.
+
+*/
+```
diff --git a/Java/Change to Anagram.java b/Java/Change to Anagram.java
new file mode 100755
index 0000000..121f7db
--- /dev/null
+++ b/Java/Change to Anagram.java
@@ -0,0 +1,103 @@
+E
+
+简单的check int[26] 26个小写字母是否需要改变。若需要count+1.
+
+主要HackerRank里要注意自己写: Scanner, import java.util, non-static method ...etc.
+
+注意: 最后count出来要除以2:字母不同,会在不同的字母位上加减count,那么就是刚好重复计算了一遍。所以除以二。
+
+```
+/*
+HackerRank CodePair
+
+Sid loves to read short stories. Being a Computer Science student, he decides to do some frequency analysis on his favorite reading material. For each data point, chooses a string of length a from one book, and a string of length b from a second book. The strings' lengths differ by no more than 1.
+|a-b|≤1, where |x| represents the absolute value function.
+
+The frequency analysis consists of checking how far the strings are from being anagrams of one another. Your challenge is to help him find the minimum number of characters of the first string he needs to change to make it an anagram of the second string. He can neither add nor delete characters from the first string. Only replacement of the characters with new ones is allowed.
+
+Input Format
+The first line will contain an integer T representing the number of test cases. Each test case will contain a string having length (a+b) which will be concatenation of both the strings described in problem. The string will only contain small letters and without any spaces.
+
+Output Format
+An integer corresponding to each test case is printed in a different line i.e., the number of changes required for each test case. Print ‘-1’ if it is not possible.
+
+Constraints
+1 ≤ T ≤ 100
+ 1 ≤ a+b ≤ 10,000
+
+Sample Input
+5
+aaabbb
+ab
+abc
+mnop
+xyyx
+Sample Output
+3
+1
+-1
+2
+0
+
+Explanation
+In the five test cases
+One string must be “aaa” and the other “bbb”. The lengths are a=3 and b=3, so the difference is less than 1. No characters are common between the strings, so all three must be changed.
+One string must be “a” and the second “b”. The lengths are a=1 and b=1, so the difference is less than 1. One character must be changed to them the same.
+Since the string lengths a and b must differ by no more than 1, the lengths are either a=1 and b=2 or a=2 and b=1. No sequence of substitutions will make the two anagrams of one another.
+One string must be “mn" and other be “op”. The length are a=2 and b=2, so the difference is less than 1. No characters are common between the strings, so both must be changed.
+One string must be “xy” and the other be “yx”. The length are a=2 and b=2, so the difference is less than 1. No changes are needed because the second string is already an anagram of the first.
+*/
+
+
+/*
+Check if they are valid string. If length == odd, then fail, -1
+Use int[26] arr to add chars from s1. If non-26-char exist, return -1
+use same int arr to remove chars from s2.
+count the non-zeros
+
+Note: the order of letters does not matter, becase all we want to change to is anagram
+*/
+import java.io.*;
+import java.util.*;
+public class Solution {
+ public static void main(String args[] ) throws Exception {
+ /* Enter your code here. Read input from STDIN. Print output to STDOUT */
+ Scanner in = new Scanner(System.in);
+ int numOfCase = Integer.parseInt(in.nextLine());
+ Solution sol = new Solution();
+
+ while (numOfCase > 0) {
+ int rst = sol.validate(in.nextLine());
+ System.out.println(rst);
+ numOfCase--;
+ }
+ }
+
+ public int validate(String str) {
+ if (str.length() % 2 == 1) {
+ return -1;
+ }
+ String sA = str.substring(0, str.length()/2);
+ String sB = str.substring(str.length()/2);
+
+ int[] arr = new int[26];
+ for (int i = 0; i < sA.length(); i++) {
+ char cA = sA.charAt(i);
+ char cB = sB.charAt(i);
+ if (cA < 'a' || cA > 'z' || cB < 'a' || cB > 'z') {
+ return -1;
+ }
+ arr[cA - 'a']++;
+ arr[cB - 'a']--;
+ }
+
+ int count = 0;
+ for (int num : arr) {
+ count += Math.abs(num);
+ }
+ return count/2;
+ }
+
+
+}
+```
\ No newline at end of file
diff --git a/Java/Classical Binary Search.java b/Java/Classical Binary Search.java
index cae325c..b4e7f42 100644
--- a/Java/Classical Binary Search.java
+++ b/Java/Classical Binary Search.java
@@ -1,5 +1,14 @@
+E
+
+ while: start + 1 < end
+ mid = start + (end - start) / 2;
+ 末尾double check start, end.
+
+
+```
/*
-Find any position of a target number in a sorted array. Return -1 if target does not exist.
+Find any position of a target number in a sorted array.
+Return -1 if target does not exist.
Example
Given [1, 2, 2, 4, 5, 5].
@@ -28,25 +37,26 @@ public class Solution {
* @return an integer
*/
public int findPosition(int[] A, int target) {
- if (A == null || A.length == 0) {
- return -1;
- }
- int start = 0;
- int end = A.length - 1;
- int mid;
- while(start + 1 < end) {
- mid = start + (end - start) / 2;
- if (target == A[mid]) {
- return mid;
- } else if (target > A[mid]) {
- start = mid;
- } else {
- end = mid;
- }
- }//end while
- if (A[start] == target || A[end] == target) {
- return A[start] == target ? start : end;
- }
- return -1;
+ if (A == null || A.length == 0) {
+ return -1;
+ }
+ int start = 0;
+ int end = A.length - 1;
+ int mid;
+ while(start + 1 < end) {
+ mid = start + (end - start) / 2;
+ if (target == A[mid]) {
+ return mid;
+ } else if (target > A[mid]) {
+ start = mid;
+ } else {
+ end = mid;
+ }
+ }//end while
+ if (A[start] == target || A[end] == target) {
+ return A[start] == target ? start : end;
+ }
+ return -1;
}
}
+```
diff --git a/Java/Climbing Stairs.java b/Java/Climbing Stairs.java
old mode 100644
new mode 100755
index 254d0b9..2fe4a33
--- a/Java/Climbing Stairs.java
+++ b/Java/Climbing Stairs.java
@@ -1,25 +1,119 @@
+E
+
+方法1: DP。爬坡到i点总共有的方法,取决于i-1点和i-2的情况。也就是DP(i-1) + DP(i-2).
+
+还可以用滚动数组优化一点:因为用到的变量就只有i,i-1,i-2,可以被替代。
+ 注意要写好‘滚动’的代码。
+
+方法2: DFS但是timeout
+
+```
/*
-40% Accepted
+
You are climbing a stair case. It takes n steps to reach to the top.
Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top?
-Example
-Tags Expand
+Dynamic Programming
+
+*/
+
+/*
+ 3.25.2016 recap DP
+ DP[i] is dependent on wether it was reached by 2 steps or just 1 step:
+ DP[i] = DP[i - 1] + DP[i - 2]
+*/
+public class Solution {
+ public int climbStairs(int n) {
+ if (n == 0) {
+ return 0;
+ }
+ if (n == 1) {
+ return 1;
+ }
+ int[] DP = new int[n + 1];
+ DP[0] = 1;
+ DP[1] = 1;
+ for (int i = 2; i <= n; i++) {
+ DP[i] = DP[i - 1] + DP[i - 2];
+ }
+ return DP[n];
+ }
+}
+
+/*
+ Based on the DP solution, think about rolling array.
+ We only make use of i, i-1, and i-2.
+ Ideally, we can reduce them just to 3 variables
+
+ 1. Replace the variable
+ 2. Implement the rotation process:
+ prev2 = prev1;
+ prev1 = rst;
+*/
+public class Solution {
+ public int climbStairs(int n) {
+ if (n == 0) {
+ return 0;
+ }
+ if (n == 1) {
+ return 1;
+ }
+ int rst = 0;
+ int prev2 = 1;
+ int prev1 = 1;
+ for (int i = 2; i <= n; i++) {
+ rst = prev1 + prev2;
+ prev2 = prev1;
+ prev1 = rst;
+ }
+ return rst;
+ }
+}
+
+/*
+ Recap 3.25.2016
+ Naturally think of dfs. Any time when n drops to <= 0, count++
+ Exceed time limit
+*/
+
+public class Solution {
+ public int count = 0;
+ public int climbStairs(int n) {
+ if (n <= 0) {
+ return 0;
+ }
+ dfs(n);
+ return count;
+ }
+
+ public void dfs(int n) {
+ if (n <= 0) {
+ count++;
+ return;
+ } else if (n == 1) {
+ count++;
+ return;
+ }
+ dfs(n - 1);
+ dfs(n - 2);
+ }
+}
+
+/*
Thinking process:
State: at i level, f[i] is the ways to climb to i position.
Function: f[i] = f[i-1] + f[i-2].
- f[i] is constructed from 2 branches:
- Last step is 1 from f[i-1]
- Last step is 2 from f[i-2]
- This idea can be presented using a tree. However we don’t need to do recursive. We just need to use two pointers to withhold 2 level’s values.
+ f[i] is constructed from 2 branches:
+ Last step is 1 from f[i-1]
+ Last step is 2 from f[i-2]
+ This idea can be presented using a tree. However we don’t need to do recursive. We just need to use two pointers to withhold 2 level’s values.
Init: The for loop starts at level2, so before level 2 there are 2 init states:
- f[0] == 1. This means we jump 2 steps from level0 to level2.
- f[i] == 1. This means we jump 1 steps to level1, then jump another step to level2
+ f[0] == 1. This means we jump 2 steps from level0 to level2.
+ f[i] == 1. This means we jump 1 steps to level1, then jump another step to level2
Answer: f[n]
*/
-
public class Solution {
/**
* @param n: An integer
@@ -42,3 +136,5 @@ public int climbStairs(int n) {
}
+
+```
\ No newline at end of file
diff --git a/Java/Clone Graph.java b/Java/Clone Graph.java
index eeaabe3..93c305e 100644
--- a/Java/Clone Graph.java
+++ b/Java/Clone Graph.java
@@ -1,3 +1,11 @@
+M
+
+Use HashMap to mark cloned nodes.
+
+先能复制多少Node复制多少。然后把neighbor 加上
+
+
+```
/*
Clone an undirected graph. Each node in the graph contains a label and a list of its neighbors.
@@ -23,7 +31,7 @@
\_/
Hide Tags Depth-first Search Breadth-first Search Graph
-
+
*/
/*
@@ -134,3 +142,5 @@ public UndirectedGraphNode cloneGraph(UndirectedGraphNode node) {
}
}
+
+```
diff --git a/Java/Closest Binary Search Tree Value.java b/Java/Closest Binary Search Tree Value.java
new file mode 100644
index 0000000..d68ba76
--- /dev/null
+++ b/Java/Closest Binary Search Tree Value.java
@@ -0,0 +1,56 @@
+E
+
+Binary Search. 记录找到过的closest. 直到tree leaf, 找完return
+
+```
+/*
+Given a non-empty binary search tree and a target value, find the value in the BST that is closest to the target.
+
+Note:
+Given target value is a floating point.
+You are guaranteed to have only one unique value in the BST that is closest to the target.
+
+Tags: Tree Binary Search
+Similar Problems: (M) Count Complete Tree Nodes, (H) Closest Binary Search Tree Value II
+
+*/
+
+
+/*
+Thoughts:
+Binary search, maintain a closest value.
+Note: initial closest in real case is just the root, since we start from the root
+*/
+/**
+ * Definition for a binary tree node.
+ * public class TreeNode {
+ * int val;
+ * TreeNode left;
+ * TreeNode right;
+ * TreeNode(int x) { val = x; }
+ * }
+ */
+public class Solution {
+ public int closestValue(TreeNode root, double target) {
+ if (root == null) {
+ return 0;
+ }
+ double closest = root.val;
+ while (root != null) {
+ if (root.val == target) {
+ return root.val;
+ } else {
+ if (Math.abs(target - closest) >= Math.abs(target - root.val)) {
+ closest = root.val;
+ }
+ if (root.val > target) {
+ root = root.left;
+ } else {
+ root = root.right;
+ }
+ }
+ }//END while
+ return (int)closest;
+ }
+}
+```
\ No newline at end of file
diff --git a/Java/Closest Number in Sorted Array.java b/Java/Closest Number in Sorted Array.java
index 29ab136..13f8231 100644
--- a/Java/Closest Number in Sorted Array.java
+++ b/Java/Closest Number in Sorted Array.java
@@ -1,5 +1,9 @@
-Binary search. 考虑mid-1, mid+1.
-一旦没有mid = target.index。 那么target最终就narrow down在(mid-1,mid) 或者(mid,mid+1)
+E
+
+跟Closest Binary Search Tree Vlaue类似:
+
+Binary search. 考虑mid-1, mid+1.
+一旦没有mid = target.index。 那么target最终就narrow down在(mid-1,mid) 或者(mid,mid+1)
```
/*
Given a target number and an integer array A sorted in ascending order, find the index i in A such that A[i] is closest to the given target.
diff --git a/Java/ColorGrid.java b/Java/ColorGrid.java
new file mode 100644
index 0000000..9fbee5c
--- /dev/null
+++ b/Java/ColorGrid.java
@@ -0,0 +1,155 @@
+M
+
+用HashMap, 理解题目规律,因为重复的计算可以被覆盖,所以是个优化题。
+
+消灭重合点:
+如果process当下col, 其实要减去过去所有加过的row的交接点。。。
+再分析,就是每次碰到row 取一个单点, sumRow += xxx。
+然后process当下col时候, sum += colValue * N - sumRow. 就等于把交叉所有row(曾经Process过的row)的点减去了。很方便。
+
+最后read in 是O(P), process也是O(P).
+
+
+```
+
+/*
+HackerRank.
+You are given an N×NN×N grid. Each cell has the color white (color 0) in the beginning.
+
+Each row and column has a certain color associated with it. Filling a row or column with a new color VV means changing all the cells of that row or column to VV (thus overriding the previous colors of the cells).
+
+Now, given a sequence of PP such operations, calculate the sum of the colors in the final grid.
+
+For simplicity, the colors will be positive integers whose values will be most 109109.
+
+Input Format
+The first line of input contains two integers NN and PP separated by a space.
+The next PP lines each contain a filling operation. There are two types of filling operations.
+
+ROW I V which means "fill row II with color VV".
+COL I V which means "fill column II with color VV".
+Output Format
+Output one line containing exactly one integer which is the sum of the colors in the final grid.
+
+Constraints
+1≤N≤60001≤N≤6000
+1≤P≤4000001≤P≤400000
+1≤I≤N1≤I≤N
+1≤V≤1091≤V≤109
+
+Sample Input
+
+5 4
+COL 1 6
+COL 4 11
+ROW 3 9
+COL 1 24
+Sample Output
+
+200
+Explanation
+There are four operations. After the second operation, the grid looks like
+
+ 6 0 0 11 0
+ 6 0 0 11 0
+ 6 0 0 11 0
+ 6 0 0 11 0
+ 6 0 0 11 0
+After the third operation (ROW 3 9), the third row was colored with 9, overriding any previous color in the cells.
+
+ 6 0 0 11 0
+ 6 0 0 11 0
+ 9 9 9 9 9
+ 6 0 0 11 0
+ 6 0 0 11 0
+After the fourth operation (COL 1 24), the grid becomes:
+
+24 0 0 11 0
+24 0 0 11 0
+24 9 9 9 9
+24 0 0 11 0
+24 0 0 11 0
+The sum of the colors in this grid is 200.
+
+*/
+
+import java.io.*;
+import java.util.*;
+import java.text.*;
+import java.math.*;
+import java.util.regex.*;
+/*
+Thoughts:
+This is for practice. I didn't run much tests on the code.
+ Store info into class Cell {int x; boolean isRow; long value}
+ Save to arraylist. Later need to call list.remove(object)
+ Use hash map to store the appearance
+ process the final data:
+ keep track of curr single row cell sum = rowSum; also colSum
+ during process: add up n*colorValue.
+ if row, minus rowSum
+ if col, minus colSum
+*/
+public class Solution {
+ class Cell {
+ int x;
+ boolean isRow;
+ long value;
+ public Cell(String s) {
+ String[] ss = s.split(" ");
+ this.isRow = ss[0].charAt(0) == 'R';
+ this.x = Integer.parseInt(ss[1]);
+ this.value = Long.parseLong(ss[2]);
+ }
+ }
+ public static void main(String[] args) {
+ Solution sol = new Solution();
+
+ Scanner in = new Scanner(System.in);
+ String[] ss = in.nextLine().split(" ");
+ int N = Integer.parseInt(ss[0]);
+ int P = Integer.parseInt(ss[1]);
+
+ //Storage
+ HashMap map = new HashMap();
+ ArrayList list = new ArrayList();
+
+ while (P != 0) {//O(P)
+ //create Cell
+ String s = in.nextLine();
+ Cell cell = sol.new Cell(s);
+ //add into list
+ list.add(cell);
+ //Check if cell exist in map.
+ //if exist in map, replace it with current cell, and remove old cell from list
+ String key = s.substring(0, s.lastIndexOf(" "));
+ if (!map.containsKey(key)) {
+ map.put(key, cell);
+ } else {
+ Cell oldCell = map.get(key);
+ map.put(key, cell);
+ list.remove(oldCell);
+ }
+ P--;
+ }
+
+ //Process final results
+ int sumCol = 0;
+ int sumRow = 0;
+ long sum = 0;
+ for (int i = 0; i < list.size(); i++) {//O(P)
+ Cell cell = list.get(i);
+ sum += cell.value * N;
+ if (cell.isRow) {
+ sum -= sumCol;
+ sumRow += cell.value;
+ } else {
+ sum -= sumRow;
+ sumCol += cell.value;
+ }
+ }
+
+ System.out.println(sum);
+ }
+}
+```
\ No newline at end of file
diff --git a/Java/Combination Sum II.java b/Java/Combination Sum II.java
index 001b450..4aa8dfd 100644
--- a/Java/Combination Sum II.java
+++ b/Java/Combination Sum II.java
@@ -1,4 +1,7 @@
-确保Helper是用i+1,下一层的数字。
+M
+
+还是DFS. 和Combination Sum I 类似.
+确保Helper是用i+1,下一层的数字, 不允许重复。
```
/*
diff --git a/Java/Combination Sum.java b/Java/Combination Sum.java
index 0566a71..a83f79f 100644
--- a/Java/Combination Sum.java
+++ b/Java/Combination Sum.java
@@ -1,5 +1,19 @@
-递归,backtracking. 非常normal。
-记得求sum时候也pass 一个sum进去,backtracking一下sum也,这样就不必每次都sum the list了。
+M
+
+递归,backtracking. 非常normal。需要先sort.
+记得求sum时候也pass 一个sum进去,backtracking一下sum也,这样就不必每次都sum the list了。
+
+题目里面所同一个元素可以用n次,但是,同一种solution不能重复出现。如何handle?
+
+1. 用一个index (我们这里用了start)来mark每次recursive的起始点。
+2. 每个recursive都从for loop里面的i开始,而i = start。 也就是,下一个iteration,这个数字会有机会被重复使用。
+3. 同时,确定在同一个for loop里面,不同的Index上面相同的数字,不Process两遍。用一个prev 作为checker.
+
+假如[x1, x2, y, z], where x1 == x2, 上面做法的效果:
+我们可能有这样的结果: x1,x1,x1,y,z
+但是不会有:x1,x2,x2,y,z
+两个solution从数字上是一样的,也就是duplicated solution, 要杜绝第二种。
+
```
/*
Given a set of candidate numbers (C) and a target number (T), find all unique combinations in C where the candidate numbers sums to T.
diff --git a/Java/Combinations.java b/Java/Combinations.java
index 2286e9b..ea6893d 100644
--- a/Java/Combinations.java
+++ b/Java/Combinations.java
@@ -1,3 +1,10 @@
+M
+
+Combination DFS。 画个图想想. 每次从1~n里面pick一个数字i
+
+因为下一层不能重新回去 [0~i]选,所以下一层recursive要从i+1开始选。
+
+```
/*
Given two integers n and k, return all possible combinations of k numbers out of 1 ... n.
@@ -14,11 +21,6 @@
*/
public class Solution {
- /**
- * @param n: Given the range of numbers
- * @param k: Given the numbers of combinations
- * @return: All the combinations of k numbers out of 1..n
- */
public List> combine(int n, int k) {
List> rst = new ArrayList>();
if (n <= 0 || k <= 0) {
@@ -42,3 +44,5 @@ public void helper(List> rst,
}
}
+
+```
\ No newline at end of file
diff --git a/Java/Compare Strings.java b/Java/Compare Strings.java
index 1cf9b3a..8d83fc4 100644
--- a/Java/Compare Strings.java
+++ b/Java/Compare Strings.java
@@ -1,3 +1,10 @@
+E
+
+比较一下大小, null.
+
+然后用char[]来count chars from A. 再对照chars in B.
+
+```
/*
Compare two strings A and B, determine whether A contains all of the characters in B.
@@ -42,3 +49,5 @@ public boolean compareStrings(String A, String B) {
}
}
+
+```
\ No newline at end of file
diff --git a/Java/Complete Binary Tree.java b/Java/Complete Binary Tree.java
index 03fbba4..93c7027 100644
--- a/Java/Complete Binary Tree.java
+++ b/Java/Complete Binary Tree.java
@@ -1,8 +1,12 @@
-Use a flag . 当出现了第一次有 null children的node的时候,
-说明complete tree的最低level出现了。
-自此以后,再不该有node再有child, queue后面出现的node应该左右孩子都是null.
+E
+
+BFS
+
+Use a flag . 当出现了第一次有 null children的node的时候,
+说明complete tree的最低level出现了。
+自此以后,queue再不该有node再有child, queue后面出现的node的左右孩子应该都是null.
+
-用BFS
```
/*
Check a binary tree is completed or not. A complete binary tree is not binary tree that every level is completed filled except the deepest level. In the deepest level, all nodes must be as left as possible. See more definition
diff --git a/Java/Construct Binary Tree from Inorder and Postorder Traversal.java b/Java/Construct Binary Tree from Inorder and Postorder Traversal.java
old mode 100644
new mode 100755
index fcdb29a..d23e140
--- a/Java/Construct Binary Tree from Inorder and Postorder Traversal.java
+++ b/Java/Construct Binary Tree from Inorder and Postorder Traversal.java
@@ -1,3 +1,15 @@
+M
+
+写个Inorder和Postorder的例子。利用他们分left/right subtree的规律解题。
+
+Postorder array 的末尾, 就是当下层的root.
+在Inorder array 里面找到这个root,就刚好把左右两边分割成left/right tree。
+
+这题比较tricky地用了一个helper做recursive。 特别要注意处理index的变化, precisely考虑开头结尾
+
+可惜有个不可避免的O(n) find element in array.
+
+```
/*
Given inorder and postorder traversal of a tree, construct the binary tree.
@@ -19,18 +31,18 @@
Thinking process:
Know that the last element of PostOrder array is the root of the Binary tree.
-Find this root from the InOrder array, which will be the middle point. The front-part of the inorder array will be left-tree, the end-part of the inorder array will be the right-tree.
+Find this root from the InOrder array. The front-part of the inorder array will be left-tree, the end-part of the inorder array will be the right-tree.
Trick part:
1. Need a helper function to perfrom divide/conquer.
2. Need to be careful when cutting the inorder and postorder array.
- For inorder array, left array: (instart, middlePosition -1), right array: (middlePosition + 1, inend)
- For postorder array: when cutting, we know the very last node is cut off already, so we just need to evenly split the rest array.
- left array(postStart, postStart + (middlePosition - instart) - 1).
- Note: (middlePositon - instart) means the length of the left-array/size of the left-tree
- However, postStart + left-array-length exceed 1 over postorder-left-tree, hence minus 1 here.
- right array(postStart + (middlePosition - instart), postend - 1)
- Note: postStart + left-tree-length is exactly the starting point of the post-right-array.
- Because the ending element is cut off previously to serve as root, we need to do (postend - 1) for correct postorder-right-tree.
+ For inorder array, left array: (instart, middlePosition -1), right array: (middlePosition + 1, inend)
+ For postorder array: when cutting, we know the very last node is cut off already, so we just need to evenly split the rest array.
+ left array(postStart, postStart + (middlePosition - instart) - 1).
+ Note: (middlePositon - instart) means the length of the left-array/size of the left-tree
+ However, postStart + left-array-length exceed 1 over postorder-left-tree, hence minus 1 here.
+ right array(postStart + (middlePosition - instart), postend - 1)
+ Note: postStart + left-tree-length is exactly the starting point of the post-right-array.
+ Because the ending element is cut off previously to serve as root, we need to do (postend - 1) for correct postorder-right-tree.
*/
@@ -48,11 +60,7 @@ Because the ending element is cut off previously to serve as root, we need to do
public class Solution {
- /**
- *@param inorder : A list of integers that inorder traversal of a tree
- *@param postorder : A list of integers that postorder traversal of a tree
- *@return : Root of a tree
- */
+
public TreeNode buildTree(int[] inorder, int[] postorder) {
if (inorder.length != postorder.length) {
return null;
@@ -85,3 +93,5 @@ public int findMid(int[] arr, int start, int end, int key) {
}
}
+
+```
\ No newline at end of file
diff --git a/Java/Construct Binary Tree from Inorder and Preorder Traversal.java b/Java/Construct Binary Tree from Inorder and Preorder Traversal.java
old mode 100644
new mode 100755
index 3026d0d..fb69f8b
--- a/Java/Construct Binary Tree from Inorder and Preorder Traversal.java
+++ b/Java/Construct Binary Tree from Inorder and Preorder Traversal.java
@@ -1,3 +1,10 @@
+M
+
+和Construct from Inorder && Postorder 想法一样。
+
+写出Preorder和Inorder的字母例子,发现Preorder的开头总是这Level的root。依此写helper,注意处理index。
+
+```
/*
Given preorder and inorder traversal of a tree, construct the binary tree.
@@ -39,11 +46,6 @@
public class Solution {
- /**
- *@param preorder : A list of integers that preorder traversal of a tree
- *@param inorder : A list of integers that inorder traversal of a tree
- *@return : Root of a tree
- */
public TreeNode buildTree(int[] preorder, int[] inorder) {
if (preorder.length != inorder.length) {
return null;
@@ -77,3 +79,5 @@ public int findMid(int[] arr, int start, int end, int key) {
}
}
+
+```
\ No newline at end of file
diff --git a/Java/Convert Binary Search Tree to Doubly Linked List.java b/Java/Convert Binary Search Tree to Doubly Linked List.java
index 2efc30d..c977d71 100644
--- a/Java/Convert Binary Search Tree to Doubly Linked List.java
+++ b/Java/Convert Binary Search Tree to Doubly Linked List.java
@@ -1,15 +1,19 @@
-注意inorder traversal在check right node的事后,
-不论right == null or != null, 每次都要强行move to right.
+M
+
+会iterative traverse Binary Search Tree就好(Stack && handle left-dig-down), 然后create Doubly-ListNode 时候注意就好.
+
+注意inorder traversal在check right node的事后,
+不论right == null or != null, 每次都要强行move to right.
+
+如果不node = node.right,
+很可能发生窘境:
+node alays = stack.top(), 然后stack.top()一直是一开始把left 全部遍历的内容。所以就会infinite loop, 永远在左边上下上下。
-如果不node = node.right,
-很可能发生窘境:
-node alays = stack.top(), 然后stack.top()一直是一开始把left 全部遍历的内容。所以就会infinite loop, 永远在左边上下上下。
```
/*
Convert a binary search tree to doubly linked list with in-order traversal.
-Have you met this question in a real interview? Yes
Example
Given a binary search tree:
@@ -58,10 +62,6 @@
boarder case: if null, return a null.
*/
public class Solution {
- /**
- * @param root: The root of tree
- * @return: the head of doubly list node
- */
public DoublyListNode bstToDoublyList(TreeNode root) {
if (root == null) {
return null;
diff --git a/Java/Convert Expression to Polish Notation.java b/Java/Convert Expression to Polish Notation.java
old mode 100644
new mode 100755
index 7046567..6c33ca3
--- a/Java/Convert Expression to Polish Notation.java
+++ b/Java/Convert Expression to Polish Notation.java
@@ -1,5 +1,11 @@
+H
+
还是Expression Tree (Min-Tree).
+
根据题意,Tree出来以后,来个Pre-order-traversal.
+
+Note: label需要是String.虽然 Operator是长度为1的char, 但是数字可为多位。
+
```
/*
Given an expression string array, return the Polish notation of this expression. (remove the parentheses)
@@ -25,93 +31,94 @@
*/
public class Solution {
- class TreeNode {
- String s;
- int val;
- TreeNode left;
- TreeNode right;
- public TreeNode(int val, String s) {
- this.val = val;
- this.s = s;
- this.left = null;
- this.right = null;
- }
- }
-
- public TreeNode build(String[] expression) {
- if (expression == null || expression.length == 0) {
- return null;
- }
- Stack stack = new Stack();
- int base = 0;
- int val = 0;
-
- for (int i = 0; i < expression.length; i++) {
- if (expression[i].equals("(")) {
- base += 10;
- continue;
- }
- if (expression[i].equals(")")) {
- base -= 10;
- continue;
- }
- val = getWeight(base, expression[i]);
- TreeNode node = new TreeNode(val, expression[i]);
- while (!stack.isEmpty() && node.val <= stack.peek().val) {
- node.left = stack.pop();
- }
- if (!stack.isEmpty()) {
- stack.peek().right = node;
- }
- stack.push(node);
- }
- if (stack.isEmpty()) {
- return null;
- }
- TreeNode rst = stack.pop();
- while (!stack.isEmpty()) {
- rst = stack.pop();
- }
- return rst;
- }
-
- public int getWeight(int base, String s) {
- if (s.equals("+") || s.equals("-")) {
- return base + 1;
- }
- if (s.equals("*") || s.equals("/")) {
- return base + 2;
- }
- return Integer.MAX_VALUE;
- }
+ class TreeNode {
+ String s;
+ int val;
+ TreeNode left;
+ TreeNode right;
+ public TreeNode(int val, String s) {
+ this.val = val;
+ this.s = s;
+ this.left = null;
+ this.right = null;
+ }
+ }
+
+ public TreeNode build(String[] expression) {
+ if (expression == null || expression.length == 0) {
+ return null;
+ }
+ Stack stack = new Stack();
+ int base = 0;
+ int val = 0;
+
+ for (int i = 0; i < expression.length; i++) {
+ if (expression[i].equals("(")) {
+ base += 10;
+ continue;
+ }
+ if (expression[i].equals(")")) {
+ base -= 10;
+ continue;
+ }
+ val = getWeight(base, expression[i]);
+ TreeNode node = new TreeNode(val, expression[i]);
+ while (!stack.isEmpty() && node.val <= stack.peek().val) {
+ node.left = stack.pop();
+ }
+ if (!stack.isEmpty()) {
+ stack.peek().right = node;
+ }
+ stack.push(node);
+ }
+ if (stack.isEmpty()) {
+ return null;
+ }
+ TreeNode rst = stack.pop();
+ while (!stack.isEmpty()) {
+ rst = stack.pop();
+ }
+ return rst;
+ }
+
+ public int getWeight(int base, String s) {
+ if (s.equals("+") || s.equals("-")) {
+ return base + 1;
+ }
+ if (s.equals("*") || s.equals("/")) {
+ return base + 2;
+ }
+ return Integer.MAX_VALUE;
+ }
/**
* @param expression: A string array
* @return: The Polish notation of this expression
*/
public ArrayList convertToPN(String[] expression) {
- ArrayList rst = new ArrayList();
- if (expression == null || expression.length == 0) {
- return rst;
- }
- TreeNode root = build(expression);
- preTraversal(rst, root);
-
- return rst;
+ ArrayList rst = new ArrayList();
+ if (expression == null || expression.length == 0) {
+ return rst;
+ }
+ TreeNode root = build(expression);
+ preTraversal(rst, root);
+
+ return rst;
}
public void preTraversal(ArrayList rst, TreeNode node){
- if (node == null) {
- return;
- }
- if (node.left == null && node.right == null) {
- rst.add(node.s);
- return;
- }
- rst.add(node.s);
- preTraversal(rst, node.left);
- preTraversal(rst, node.right);
+ if (node == null) {
+ return;
+ }
+ if (node.left == null && node.right == null) {
+ rst.add(node.s);
+ return;
+ }
+ rst.add(node.s);
+ preTraversal(rst, node.left);
+ preTraversal(rst, node.right);
}
}
+
```
\ No newline at end of file
diff --git a/Java/Convert Expression to Reverse Polish Notation.java b/Java/Convert Expression to Reverse Polish Notation.java
old mode 100644
new mode 100755
index 6b0df9f..26e9c73
--- a/Java/Convert Expression to Reverse Polish Notation.java
+++ b/Java/Convert Expression to Reverse Polish Notation.java
@@ -1,6 +1,11 @@
-用build expression tree开头。
+H
+
+build expression tree。
+
这个里面把TreeNode就当做成我们需要的node,里面扩展成有left/right child的node.
-这题,目的是建造tree,然后来个post-traversal就行了。
+
+建造Expression Tree,然后根据 Reverse Polish Notation 的定义,来个post-traversal就行了。
+
```
/*
Given an expression string array, return the Reverse Polish notation of this expression. (remove the parentheses)
diff --git a/Java/Convert Integer A to Integer B.java b/Java/Convert Integer A to Integer B.java
index 97b3974..35ce992 100644
--- a/Java/Convert Integer A to Integer B.java
+++ b/Java/Convert Integer A to Integer B.java
@@ -1,3 +1,14 @@
+E
+
+Bit Manipulation
+
+a^b 显示出bit format里面有不同binary code的数位.
+
+每次 (a^b)>>i 移动i位之后, 再 & 1时其实是指留下这一位的数字.
+
+count it up
+
+```
/*
Determine the number of bits required to convert integer A to integer B
@@ -32,3 +43,5 @@ public static int bitSwapRequired(int a, int b) {
};
+
+```
\ No newline at end of file
diff --git a/Java/Convert Sorted Array to Binary Search Tree With Minimal Height.java b/Java/Convert Sorted Array to Binary Search Tree With Minimal Height.java
index dccdbe6..4d54131 100644
--- a/Java/Convert Sorted Array to Binary Search Tree With Minimal Height.java
+++ b/Java/Convert Sorted Array to Binary Search Tree With Minimal Height.java
@@ -1,3 +1,8 @@
+E
+
+Binary Search的感觉. 中间一开两半, divde and conquer,左右各自recursive下去build left/right child.
+
+```
/*
Given a sorted (increasing order) array, Convert it to create a binary tree with minimal height.
@@ -19,8 +24,8 @@ Given a sorted (increasing order) array, Convert it to create a binary tree with
Thoughts:
1. Find middle point x.
2. All index before x, goes to left of the tree. Same apply to right tree
- build sub array and pass alone: we can pass index start, end.
- use parent node and pass along
+ build sub array and pass alone: we can pass index start, end.
+ use parent node and pass along
3. Recur on left side array.
*/
@@ -45,22 +50,24 @@ public class Solution {
public TreeNode sortedArrayToBST(int[] A) {
TreeNode root = null;
if (A == null || A.length == 0) {
- return root;
+ return root;
}
root = helper(0, A.length - 1, A);
return root;
}
public TreeNode helper(int start, int end, int[] A) {
- if (start > end) {
- return null;
- }
- //add middle node
- int mid = start + (end - start)/2;
- TreeNode node = new TreeNode(A[mid]);
- //Split and append child
- node.left = helper(start, mid - 1, A);
- node.right = helper(mid + 1, end, A);
- return node;
+ if (start > end) {
+ return null;
+ }
+ //add middle node
+ int mid = start + (end - start)/2;
+ TreeNode node = new TreeNode(A[mid]);
+ //Split and append child
+ node.left = helper(start, mid - 1, A);
+ node.right = helper(mid + 1, end, A);
+ return node;
}
}
+
+```
\ No newline at end of file
diff --git a/Java/Convert Sorted List to Binary Search Tree.java b/Java/Convert Sorted List to Binary Search Tree.java
index 3295e98..a7ca482 100644
--- a/Java/Convert Sorted List to Binary Search Tree.java
+++ b/Java/Convert Sorted List to Binary Search Tree.java
@@ -1,14 +1,17 @@
-Divide and Conquer
+M
-找到mid。
-然后把root = mid.next
+Divide and Conquer
+用快慢pointer
-然后开始sortedListToBST(mid.next.next); //后半段
-mid.next = null;//非常重要,要把后面拍过序的断掉
-sortedListToBST(head); //从头开始的前半段
+找到mid。
+然后把root = mid.next
+然后开始sortedListToBST(mid.next.next); //后半段
+mid.next = null;//非常重要,要把后面拍过序的断掉
+sortedListToBST(head); //从头开始的前半段
-最后root.left, root.right merge一下。
+
+最后root.left, root.right merge一下。
```
/*
diff --git a/Java/Copy List with Random Pointer.java b/Java/Copy List with Random Pointer.java
old mode 100644
new mode 100755
index 481895f..8b9facb
--- a/Java/Copy List with Random Pointer.java
+++ b/Java/Copy List with Random Pointer.java
@@ -1,15 +1,25 @@
+M
+
+Basic Implementation, 其中用了一下HashMap:
+
+遍历head.next .... null.
+每一步都check map里面有没有head。没有?加上。
+每一步都check map里面有没有head.random。没有?加上。
+
+```
/*
-31% Accepted
+
A linked list is given such that each node contains an additional random pointer
which could point to any node in the list or null.
Return a deep copy of the list.
-Example
-Tags Expand
-Hash Table Linked List
+Hide Company Tags Microsoft Uber
+Hide Tags Hash Table Linked List
+Hide Similar Problems (M) Clone Graph
-*/
+LeetCode: Hard
+*/
/**
* Definition for singly-linked list with a random pointer.
@@ -31,16 +41,14 @@
border case: if head == null, return null
*/
-
public class Solution {
public RandomListNode copyRandomList(RandomListNode head) {
if (head == null) {
return null;
}
//creat node, used to link all nodes
- RandomListNode dummy = new RandomListNode(0);
- RandomListNode node = dummy;
- RandomListNode newNode;
+ RandomListNode node = new RandomListNode(0);
+ RandomListNode dummy = node;
//HashMap to mark node
HashMap map = new HashMap();
@@ -50,15 +58,13 @@ public RandomListNode copyRandomList(RandomListNode head) {
if (!map.containsKey(head)) {
map.put(head, new RandomListNode(head.label));
}
- newNode = map.get(head);
- node.next = newNode;
+ node.next = map.get(head);
//process head.random
if (head.random != null) {
if(!map.containsKey(head.random)) {
map.put(head.random, new RandomListNode(head.random.label));
}
- newNode = map.get(head.random);
- node.next.random = newNode;
+ node.next.random = map.get(head.random);
}
node = node.next;
head = head.next;
@@ -67,6 +73,7 @@ public RandomListNode copyRandomList(RandomListNode head) {
}
}
+
/*
Thinking process:
1. Loop through the original list
@@ -80,10 +87,6 @@ public RandomListNode copyRandomList(RandomListNode head) {
*/
public class Solution {
- /**
- * @param head: The head of linked list with a random pointer.
- * @return: A new head of a deep copy of the list.
- */
public RandomListNode copyRandomList(RandomListNode head) {
if (head == null) {
return null;
@@ -118,3 +121,44 @@ public RandomListNode copyRandomList(RandomListNode head) {
}
}
+//Same soluton as above, but split populating map && deep copy, which is not as efficient as above
+//Save all possible nodes into HashMap
+ //Deep copy the list, before adding any node, check map
+public class Solution {
+ public RandomListNode copyRandomList(RandomListNode head) {
+ if (head == null) {
+ return null;
+ }
+ //Populate map
+ HashMap map = new HashMap();
+ RandomListNode node = head;
+ RandomListNode newNode;
+ while(node != null) {
+ if (!map.containsKey(node)) {
+ newNode = new RandomListNode(node.label);
+ map.put(node, newNode);
+ }
+ if (node.random != null && !map.containsKey(node.random)) {
+ newNode = new RandomListNode(node.random.label);
+ map.put(node.random, newNode);
+ }
+ node = node.next;
+ }
+ //Deep copy
+ node = head;
+ newNode = new RandomListNode(0);
+ RandomListNode dummy = newNode;
+ while (node != null) {
+ newNode.next = map.get(node);
+ if (node.random != null)
+ newNode.next.random = map.get(node.random);
+ newNode = newNode.next;
+
+ node = node.next;
+ }
+
+ return dummy.next;
+ }
+}
+
+```
\ No newline at end of file
diff --git a/Java/Cosine Similarity.java b/Java/Cosine Similarity.java
index c71919e..afa16bb 100644
--- a/Java/Cosine Similarity.java
+++ b/Java/Cosine Similarity.java
@@ -1,7 +1,11 @@
-按题目意思,写出来就好了。
+E
+
+basic implementation
+
```
/*
-Cosine similarity is a measure of similarity between two vectors of an inner product space that measures the cosine of the angle between them.
+Cosine similarity is a measure of similarity between two vectors of an inner product space
+ that measures the cosine of the angle between them.
The cosine of 0° is 1, and it is less than 1 for any other angle.
See wiki: Cosine Similarity
diff --git a/Java/Count 1 in Binary.java b/Java/Count 1 in Binary.java
index 1059210..f44a5c3 100644
--- a/Java/Count 1 in Binary.java
+++ b/Java/Count 1 in Binary.java
@@ -1,3 +1,10 @@
+E
+
+1. 可以把integer -> string -> char array.
+
+2. 或者就 count += num << i & 1
+
+```
/*
Count how many 1 in binary representation of a 32-bit integer.
@@ -41,3 +48,5 @@ public int countOnes(int num) {
return sum;
}
};
+
+```
\ No newline at end of file
diff --git a/Java/Count Primes.java b/Java/Count Primes.java
new file mode 100644
index 0000000..2888f30
--- /dev/null
+++ b/Java/Count Primes.java
@@ -0,0 +1,88 @@
+E
+
+什么是prime number: >=2的没有除自己和1以外公约数的数。
+
+还有另外一个定义方法!!
+这个n,有没有小于n的一个i,而达到: i*i + # of i = n. 如果有,那就不是 prime。
+
+方法很牛逼也很数学。没做的时候可能想不到。做了之后就觉得,哎,我去,有道理啊。
+简而言之:简历一个boolean长条,存isPrime[]。 然后从i=2, 全部变true.
+然后利用这个因子的性质,非prime满足条件: self*self, self * self + self ... etc.
+所以就check每一个j, j+i, j+i+i, 然后把所有non-prime全部mark成false.
+最后,数一遍还剩下的true个数就好了
+
+```
+/*
+Description:
+Count the number of prime numbers less than a non-negative number, n.
+Tags: Hash Table, Math
+Similar Problems: (E) Ugly Number, (M) Ugly Number II, (M) Perfect Squares
+*/
+
+/*
+Attempt2: https://leetcode.com/problems/count-primes/ explains it well
+1. Ignore 1 and n. Don't count 1 and the number itself in.
+2. Assume all numbers are prime in a boolean[]. Check off those are certainly not prime, the remaining will be prime.
+3. For any n, only need to check up to i * i < n; more than that,
+for example 2 x 6 is same as checking 6x2, but 6x2 is not necessary to check.
+4. How to mark things off:
+ The first non-prime is always i^2: self * self.
+ Then more non-primes:self * self, self * (self + 1), self * (self + 2) ... etc.
+ So, mark all of these index of in the boolean[]
+
+*/
+public class Solution {
+ public int countPrimes(int n) {
+ if (n <= 1) {
+ return 0;
+ }
+ boolean[] primes = new boolean[n];
+ for (int i = 2; i < primes.length; i++) {
+ primes[i] = true;
+ }
+
+ for (int i = 2; i * i< n; i++) {
+ if (!primes[i]) {
+ continue;
+ }
+ for (int j = i * i; j < n; j += i) {
+ primes[j] = false;
+ }
+ }
+ int count = 0;
+ for (int i = 2; i < primes.length; i++) {
+ count += primes[i] ? 1 : 0;
+ }
+ return count;
+ }
+}
+
+
+/*Timeout version*/
+//prime is a number n that cannot be divided by any number < n.
+//In fact, only need to check sqrt(n) numbers from 1
+
+public class Solution {
+ public int countPrimes(int n) {
+ int count = 0;
+ for (int i = 1; i < n; i++) {
+ if (isPrime(i)) {
+ count++;
+ }
+ }
+ return count;
+ }
+
+ public boolean isPrime(int num) {
+ if (num <= 1) return false;
+ for (int i = 2; i * i <= num; i++) {
+ if (num % i == 0) {
+ return false;
+ }
+ }
+ return true;
+ }
+}
+
+
+```
\ No newline at end of file
diff --git a/Java/Count and Say.java b/Java/Count and Say.java
index 2d0fc5b..76637a7 100644
--- a/Java/Count and Say.java
+++ b/Java/Count and Say.java
@@ -1,3 +1,8 @@
+E
+
+Basic implementation. Count duplicates and print
+
+```
/*
The count-and-say sequence is the sequence of integers beginning as follows:
@@ -40,23 +45,25 @@ public String countAndSay(int n) {
String str = "11";
int ind = 2;
while (ind < n) {
- StringBuffer sb = new StringBuffer();
- char[] arr = str.toCharArray();
- int count = 1;
- int type = Character.getNumericValue(arr[0]);
- for (int i = 1; i < arr.length; i++) {
- if (arr[i] == arr[i - 1]) {
- count++;
- } else {
- sb.append(count + "" + type);
- type = Character.getNumericValue(arr[i]);
- count = 1;
- }
- }
- ind++;
- sb.append(count + "" + type);
- str = sb.toString();
+ StringBuffer sb = new StringBuffer();
+ char[] arr = str.toCharArray();
+ int count = 1;
+ int type = Character.getNumericValue(arr[0]);
+ for (int i = 1; i < arr.length; i++) {
+ if (arr[i] == arr[i - 1]) {
+ count++;
+ } else {
+ sb.append(count + "" + type);
+ type = Character.getNumericValue(arr[i]);
+ count = 1;
+ }
+ }
+ ind++;
+ sb.append(count + "" + type);
+ str = sb.toString();
}
return str;
}
}
+
+```
\ No newline at end of file
diff --git a/Java/Count of Smaller Number before itself.java b/Java/Count of Smaller Number before itself.java
old mode 100644
new mode 100755
index 1d0b9a8..87df7ee
--- a/Java/Count of Smaller Number before itself.java
+++ b/Java/Count of Smaller Number before itself.java
@@ -1,21 +1,28 @@
-与Count of Smaller Number非常类似。
-Trick: 先Query,再modify.
-每次Query时候,A[i]都还没有加入到Segment Tree 里面,而A[i+1...etc]自然也还没有加进去。
-那么就自然是coutning smaller number before itself.
-刁钻啊!
+H
+
+与Count of Smaller Number非常类似。以实际的value来构成segment tree,leaf上存(count of smaller number)。
+
+Trick: 先Query,再modify.
+每次Query时候,A[i]都还没有加入到Segment Tree 里面,而A[i+1,...etc]自然也还没有加进去。
+那么就自然是coutning smaller number before itself.
+刁钻啊!
+
+另外注意:
+在modify里面:多Check了root.start <= index 和 index <= root.end。 过去都忽略了。以后可以把这个也写上。
+(其实是Make sense的,就是更加严格地check了index再 root.left 或者 root.right里面的站位)
-另外注意:
-在modify里面:多Check了root.start <= index 和 index <= root.end。 过去都忽略了。以后可以把这个也写上。
-(其实是Make sense的,就是更加严格地check了index再 root.left 或者 root.right里面的站位)
```
/*
-Give you an integer array (index from 0 to n-1, where n is the size of this array, value from 0 to 10000) . For each element Ai in the array, count the number of element before this element Ai is smaller than it and return count number array.
+Give you an integer array (index from 0 to n-1, where n is the size of this array, value from 0 to 10000) .
+For each element Ai in the array, count the number of element before this element Ai is smaller than
+it and return count number array.
Example
For array [1,2,7,8,5], return [0,1,2,3,2]
Note
-We suggest you finish problem Segment Tree Build, Segment Tree Query II and Count of Smaller Number before itself I first.
+We suggest you finish problem Segment Tree Build, Segment Tree Query II and
+Count of Smaller Number before itself I first.
Tags Expand
LintCode Copyright Binary Tree Segment Tree
diff --git a/Java/Count of Smaller Number.java b/Java/Count of Smaller Number.java
old mode 100644
new mode 100755
index c8b4083..69e7096
--- a/Java/Count of Smaller Number.java
+++ b/Java/Count of Smaller Number.java
@@ -1,15 +1,33 @@
-和平时的segment tree问题不同。
-这个给了实际的value,而还是造一个based on index的segment tree才行。
-Thought1是失败的,因为虽然省了空间,但是search time还是O(n).
-Thought2才是真正的segment tree (based on index interval).
+M
+
+和平时的segment tree问题不同。 0 ~ n-1代表实际数字。是造一个based on real value的segment tree.
+Modify时,把array里面的value带进去,找到特定的位子(leaf),然后count+1.
+
+最终在SegmentTree leaf上面全是array里面实际的数字。
+
+trick:
+在query前,给进去的start和end是: 0 ~ value-1.
+value-1就是说,找比自己所在range小1的range(那么自然而然地就不包括自己了),这样就找到了smaller number.
+
+
+[那么其他做过的SegmentTree是怎么样呢?]
+那些构成好的SegmentTree(找min,max,sum)也有一个Array。但是构成Tree时候,随Array的index而构架。
+也就是说,假如有Array[x,y,....]:在leaf,会有[0,0] with value = x. [1,1] with value = y.
+
+[但是这题]
+构成时,是用actual value.也就是比如Array[x,y,....]会产生leaf:[x,x]with value = ..; [y,y]with value =...
+
+其实很容易看穿:
+若给出一个固定的array构成 SegmentTree,那估计很简单:按照index从0~array.lengh,leaf上就是[0,0] with value = x.
+
+若题目让构造一个空心SegmentTree, based on value 0 ~ n-1 (n <= 10000), 然后把一个Array的value modify 进去。
+这样八成是另外一种咯。
-重要trick:
-在query前,给进去的start和end是: 0 ~ value-1.
-value-1就是说,找比自己所在range小1的range(那么自然而然地就不包括自己了),这样就找到了smaller number.
-这个trick还挺刁钻的。
```
/*
-Give you an integer array (index from 0 to n-1, where n is the size of this array, value from 0 to 10000) and an query list. For each query, give you an integer, return the number of element in the array that are smaller than the given integer.
+Give you an integer array (index from 0 to n-1, where n is the size of this array, value from 0 to 10000)
+and an query list. For each query, give you an integer, return the number of element in the array that
+are smaller than the given integer.
Example
@@ -27,6 +45,11 @@ Give you an integer array (index from 0 to n-1, where n is the size of this arra
Tags Expand
Binary Search LintCode Copyright Segment Tree
+*/
+
+/*
+Thought1是失败的,因为虽然省了空间,但是search time还是O(n).
+Thought2才是真正的segment tree (based on index interval).
*/
/*
Thought2: http://www.jiuzhang.com/solutions/count-of-smaller-number/
@@ -34,9 +57,10 @@ Give you an integer array (index from 0 to n-1, where n is the size of this arra
Use query method to search for final results.
Each A[i] will be stored at index value of A[i].
Count: how many numbers do we have from bottom till this level, including the A[i] itself.
- For example, at the lowest A[i] spot, SegmentTreeNode(i,i), the count == 1.
+ For example, at the lowest A[i] spot, SegmentTreeNode(i,i), the count == 1.
- Note:Again, be careful on calculating the mid. It's usually based on root.start and root.end, instead of the target start,end interval.
+ Note:Again, be careful on calculating the mid. It's usually based on root.start and root.end,
+ instead of the target start,end interval.
*/
public class Solution {
@@ -118,7 +142,7 @@ public ArrayList countOfSmallerNumber(int[] A, int[] queries) {
}
for (int value : queries) {
int count = 0;
- if (value > 0) {
+ if (value > 0) {//Given value has to be in n's range: [0, 10000]
count = query(root, 0, value - 1);
}
rst.add(count);
diff --git a/Java/Course Schedule II.java b/Java/Course Schedule II.java
new file mode 100755
index 0000000..306543a
--- /dev/null
+++ b/Java/Course Schedule II.java
@@ -0,0 +1,107 @@
+M
+
+详细的中文分析,看Course Schedule I
+
+```
+/*
+There are a total of n courses you have to take, labeled from 0 to n - 1.
+
+Some courses may have prerequisites, for example to take course 0 you have to first take course 1,
+which is expressed as a pair: [0,1]
+
+Given the total number of courses and a list of prerequisite pairs,
+return the ordering of courses you should take to finish all courses.
+
+There may be multiple correct orders, you just need to return one of them.
+If it is impossible to finish all courses, return an empty array.
+
+For example:
+
+2, [[1,0]]
+There are a total of 2 courses to take. To take course 1 you should have finished course 0. So the correct course order is [0,1]
+
+4, [[1,0],[2,0],[3,1],[3,2]]
+There are a total of 4 courses to take. To take course 3 you should have finished both courses 1 and 2.
+Both courses 1 and 2 should be taken after you finished course 0.
+So one correct course order is [0,1,2,3]. Another correct ordering is[0,2,1,3].
+
+Note:
+The input prerequisites is a graph represented by a list of edges, not adjacency matrices. Read more about how a graph is represented.
+
+click to show more hints.
+
+Hints:
+This problem is equivalent to finding the topological order in a directed graph. If a cycle exists, no topological ordering exists and therefore it will be impossible to take all courses.
+Topological Sort via DFS - A great video tutorial (21 minutes) on Coursera explaining the basic concepts of Topological Sort.
+Topological sort could also be done via BFS.
+Hide Company Tags Facebook Zenefits
+Hide Tags Depth-first Search Breadth-first Search Graph Topological Sort
+Hide Similar Problems (M) Course Schedule (H) Alien Dictionary (M) Minimum Height Trees
+
+*/
+
+/*
+ http://blog.csdn.net/ljiabin/article/details/45847019
+
+ Based on Course Schedule I, now we need to return all nodes with by the seq number.
+
+ Note:
+ The map is built based on
+*/
+public class Solution {
+ HashMap> map;
+ int[] visited;
+ int seq;
+ int[] order;
+ public int[] findOrder(int numCourses, int[][] prerequisites) {
+ order = new int[numCourses];
+ seq = numCourses - 1;
+ visited = new int[numCourses];
+ map = new HashMap>();
+ //Put all start node into map.
+ for (int i = 0; i < prerequisites.length; i++) {
+ if (!map.containsKey(prerequisites[i][1])) {
+ map.put(prerequisites[i][1], new ArrayList());
+ }
+ map.get(prerequisites[i][1]).add(prerequisites[i][0]);
+ }
+ //dfs on each start node in the pair
+ for (int i = 0; i < numCourses; i++) {
+ if (!dfs(i)) {
+ return new int[]{};
+ }
+ }
+ return order;
+ }
+
+ public boolean dfs (int node) {
+ if (visited[node] == 1) {//has been through this path, true.
+ return true;
+ }
+ if (visited[node] == -1) {//visiting a visited node from a deper level node, cycle
+ return false;
+ }
+ //mark it -1 then after dfs mark it 1. Marking and backtracking skills
+ visited[node] = -1;
+
+ //Visit each child and make sure there is no cycle.
+ if (map.containsKey(node)) {
+ for (int nextNode : map.get(node)) {
+ if (!dfs(nextNode)) {
+ return false;
+ }
+ }
+ }
+ visited[node] = 1;
+ order[seq--] = node;
+ return true;
+ }
+
+}
+
+
+
+
+
+
+```
\ No newline at end of file
diff --git a/Java/Course Schedule.java b/Java/Course Schedule.java
new file mode 100755
index 0000000..ac756f7
--- /dev/null
+++ b/Java/Course Schedule.java
@@ -0,0 +1,228 @@
+M
+
+有点绕,但是做过一次就明白一点。
+是topological sort的题目。一般都是给有dependency的东西排序。
+
+最终都会到一个sink node, 再不会有向后的dependency, 在那个点截止。
+我就已这样子的点为map的key, 然后value是以这个node为prerequisite的 list of courses.
+
+画个图的话,prerequisite都是指向那个sink node, 然后我们在组成map的时候,都是从sink node 发散回来到dependent nodes.
+
+在DFS里面,我们是反向的, 然后,最先完全visited的那个node, 肯定是最左边的node了,它被mark的seq也是最高的。
+
+而我们的sink node,当它所有的支线都visit完了,seq肯定都已经减到最小了,也就是0,它就是第一个被visit的。
+
+
+最终结果:
+每个有pre-requisit的node都trace上去(自底向上),并且都没有发现cycle.也就说明schedule可以用了。
+
+```
+/*
+There are a total of n courses you have to take, labeled from 0 to n - 1.
+
+Some courses may have prerequisites, for example to take course 0 you have to first take course 1,
+which is expressed as a pair: [0,1]
+
+Given the total number of courses and a list of prerequisite pairs, is it possible for you to finish all courses?
+
+For example:
+
+2, [[1,0]]
+There are a total of 2 courses to take. To take course 1 you should have finished course 0. So it is possible.
+
+2, [[1,0],[0,1]]
+There are a total of 2 courses to take. To take course 1 you should have finished course 0,
+and to take course 0 you should also have finished course 1.
+So it is impossible.
+
+Note:
+The input prerequisites is a graph represented by a list of edges, not adjacency matrices. Read more about how a graph is represented.
+
+click to show more hints.
+
+Hints:
+1. This problem is equivalent to finding if a cycle exists in a directed graph.
+ If a cycle exists, no topological ordering exists and therefore it will be impossible to take all courses.
+2. Topological Sort via DFS - A great video tutorial (21 minutes) on Coursera explaining the basic concepts of Topological Sort.
+3. Topological sort could also be done via BFS.
+
+Hide Company Tags Zenefits
+Hide Tags Depth-first Search Breadth-first Search Graph Topological Sort
+Hide Similar Problems (M) Course Schedule II (M) Graph Valid Tree (M) Minimum Height Trees
+
+*/
+
+/*
+ Thoughts: Try some help. make shorter version.
+ This version does not use a class, but does the exact same algorithm: mark visited and check cycle with dfs.
+ The idea is almost exaclty same (http://www.jyuan92.com/blog/leetcode-course-schedule/)
+ Instead of using a seq,visited to check mark seq, and visted, we can do a 'mark' backtracking.
+ This means: we can mark the visited = -1 before the dfs, and if anything in the dfs sees a -1,
+ it returns false;
+ After the dfs of children nodes in the map, wwe mark a node.visited = 1. That means the spot has been visited : )
+
+ Note:
+ SHould build he map: map
+*/
+
+public class Solution {
+ HashMap> map;
+ int[] visited;
+ public boolean canFinish(int numCourses, int[][] prerequisites) {
+ if (numCourses <= 0 || prerequisites == null || prerequisites.length == 0 ||
+ prerequisites[0] == null || prerequisites[0].length == 0) {
+ return true;
+ }
+ visited = new int[numCourses];
+ map = new HashMap>();
+ //Put all start node into map.
+ for (int i = 0; i < prerequisites.length; i++) {
+ if (!map.containsKey(prerequisites[i][1])) {
+ map.put(prerequisites[i][1], new ArrayList());
+ }
+ map.get(prerequisites[i][1]).add(prerequisites[i][0]);
+ }
+ //dfs on each start node in the pair
+ for (int i = 0; i < prerequisites.length; i++) {
+ if (!dfs(prerequisites[i][0])) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ public boolean dfs (int node) {
+ if (visited[node] == 1) {//has been through this path, true.
+ return true;
+ }
+ if (visited[node] == -1) {//visiting a visited node from a deper level node, cycle
+ return false;
+ }
+ //mark it -1 then after dfs mark it 1. Marking and backtracking skills
+ visited[node] = -1;
+
+ //Visit each child and make sure there is no cycle.
+ if (map.containsKey(node)) {
+ for (int nextNode : map.get(node)) {
+ if (!dfs(nextNode)) {
+ return false;
+ }
+ }
+ }
+
+ visited[node] = 1;
+ return true;
+ }
+
+}
+
+
+
+
+
+
+/*
+ Thoughts: TO LONG. Should try shorter version.
+ ALSO, built the map based map: this will cause trouble and hard to work if we want to return
+ the sequence of course.
+
+ Though, no need to find the correct order of course, but we can do Topological Sort via DFS,
+ where in the process we check if there is cycle.
+ 0. Create node {val, visited, list of child node}. OR: just a map
+ 1. Put all prerequisites in map
+ 2. For loop on all nodes in the map.
+ Each node, DFS on it, add all outgoing child on stack if that node is not visited
+ Check on cycle: after DFS on all child, we need to mark the parent node itself to be visited.
+ At this moment, if this node has been visited once, that means a cycle has happended, then return false;
+
+ Implementation:
+ Use a node, track value, sequence number, and if visited, and its child nodes.
+ In DFS: first mark curr node visited, then DFS on child, then mark curr node with a sequence number.
+ Cycle: if a node has been visited but does not have a sequence number yet ,
+ (that means some nodes at the earlier level, which has no been back-tracking to yet)
+ then there must be a cycle backwards.
+*/
+public class Solution {
+ public class Node {
+ int val;
+ int seq;
+ boolean visited;
+ ArrayList children;
+ public Node(int val){
+ this.val = val;
+ this.visited = false;
+ this.children = new ArrayList();
+ this.seq = -1;
+ }
+ }
+ public int n;
+ public boolean canFinish(int numCourses, int[][] prerequisites) {
+ if (numCourses <= 0 || prerequisites == null || prerequisites.length == 0 ||
+ prerequisites[0] == null || prerequisites[0].length == 0) {
+ return true;
+ }
+ HashMap map = new HashMap();
+ for (int i = 0; i < prerequisites.length; i++) {
+ Node node;
+ //Add curr nodes
+ if (map.containsKey(prerequisites[i][0])) {
+ node = map.get(prerequisites[i][0]);
+ } else {
+ node = new Node(prerequisites[i][0]);
+ }
+ node.children.add(prerequisites[i][1]);
+ map.put(node.val, node);
+ //Add Child nodes
+ if (!map.containsKey(prerequisites[i][1])) {
+ map.put(prerequisites[i][1], new Node(prerequisites[i][1]));
+ }
+ }
+ n = prerequisites.length;
+ for (int i = 0; i < prerequisites.length; i++) {
+ if (!DFS(prerequisites[i][0], map)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ public boolean DFS(int val, HashMap map) {
+ Node node = map.get(val);
+ node.visited = true;
+ map.put(val, node);
+
+ for (int child : node.children) {
+ if (map.get(child).visited && map.get(child).seq == -1) {//Check cycle
+ return false;
+ } else if (!map.get(child).visited) {
+ if(!DFS(child, map)){
+ return false;
+ }
+ }
+ }
+
+ node.seq = n--;
+ map.put(val, node);
+ return true;
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
\ No newline at end of file
diff --git a/Java/Data Stream Median.java b/Java/Data Stream Median.java
old mode 100644
new mode 100755
index 398f50d..976fe84
--- a/Java/Data Stream Median.java
+++ b/Java/Data Stream Median.java
@@ -1,7 +1,17 @@
+H
+
+把Input stream想成向上的山坡。山坡中间那点,自然就是median.
+
+前半段,作为maxHeap,关注点是PriorityQueue的峰点,也就是实际上的median.
+
+后半段,作为minHeap,正常的PriorityQueue。 开头是最小的。
+
+Note:题目定义meadian = A[(n-1)/2],也就是说maxHeap需要和minHeap长度相等,或者多一个element,最后可以直接poll() and return.
+
+```
/*
Numbers keep coming, return the median of numbers at every time a new number added.
-Have you met this question in a real interview? Yes
Example
For numbers coming list: [1, 2, 3, 4, 5], return [1, 1, 2, 2, 3].
@@ -13,7 +23,9 @@
Total run time in O(nlogn).
Clarification
-What's the definition of Median? - Median is the number that in the middle of a sorted array. If there are n numbers in a sorted array A, the median is A[(n - 1) / 2]. For example, if A=[1,2,3], median is 2. If A=[1,19], median is 1.
+What's the definition of Median? - Median is the number that in the middle of a sorted array.
+If there are n numbers in a sorted array A, the median is A[(n - 1) / 2].
+For example, if A=[1,2,3], median is 2. If A=[1,19], median is 1.
Tags Expand
LintCode Copyright Heap Priority Queue
@@ -60,3 +72,5 @@ public int compare(Integer x, Integer y) {
return rst;
}
}
+
+```
\ No newline at end of file
diff --git a/Java/Delete Digits.java b/Java/Delete Digits.java
old mode 100644
new mode 100755
index a9eaa58..8dbe31c
--- a/Java/Delete Digits.java
+++ b/Java/Delete Digits.java
@@ -1,5 +1,11 @@
+M
+
+数位靠前的,权值更大. 所以硬来把靠前的相对更大的(跟following digit相比)去掉。
+
+```
/*
-Given string A representative a positive integer which has N digits, remove any k digits of the number, the remaining digits are arranged according to the original order to become a new positive integer.
+Given string A representative a positive integer which has N digits, remove any k digits of the number,
+the remaining digits are arranged according to the original order to become a new positive integer.
Find the smallest integer after remove k digits.
@@ -13,6 +19,10 @@
Tags Expand
Greedy LintCode Copyright
+*/
+
+/*
+
Attempt2,Thoughts:
loop k times: each interation, find one digit to remove
Rules: want to remove whatever digit at A[i] that's A[i] > A[i+1].
@@ -21,14 +31,9 @@ Well... thinking straight (attempt2) seems much easier to understand and to code
Note:
remember to remove the prefixing 0's
-*/
+*/
public class Solution {
- /**
- *@param A: A positive integer which has N digits, A is a string.
- *@param k: Remove k digits.
- *@return: A string
- */
public String DeleteDigits(String A, int k) {
if (A == null || A.length() == 0 || k == 0) {
return A;
@@ -112,3 +117,5 @@ public static String DeleteDigits(String A, int k) {
}
}
+
+```
\ No newline at end of file
diff --git a/Java/Delete Node in the Middle of Singly Linked List.java b/Java/Delete Node in the Middle of Singly Linked List.java
old mode 100644
new mode 100755
index 355deb8..cac5705
--- a/Java/Delete Node in the Middle of Singly Linked List.java
+++ b/Java/Delete Node in the Middle of Singly Linked List.java
@@ -1,3 +1,8 @@
+E
+
+Just do it. Link curr.next to curr.next.next
+
+```
/*
Implement an algorithm to delete a node in the middle of a singly linked list, given only access to that node.
@@ -32,9 +37,11 @@ public class Solution {
*/
public void deleteNode(ListNode node) {
if (node == null) {
- return;
+ return;
}
node.val = node.next.val;
node.next = node.next.next;
}
}
+
+```
\ No newline at end of file
diff --git a/Java/Distinct Subsequences.java b/Java/Distinct Subsequences.java
old mode 100644
new mode 100755
index 35cf479..eaecb5d
--- a/Java/Distinct Subsequences.java
+++ b/Java/Distinct Subsequences.java
@@ -1,7 +1,14 @@
+H
+
+Not Done
+
+```
/*
Given a string S and a string T, count the number of distinct subsequences of T in S.
-A subsequence of a string is a new string which is formed from the original string by deleting some (can be none) of the characters without disturbing the relative positions of the remaining characters. (ie, "ACE" is a subsequence of "ABCDE" while "AEC" is not).
+A subsequence of a string is a new string which is formed from the original string by deleting some (can be none)
+of the characters without disturbing the relative positions of the remaining characters.
+(ie, "ACE" is a subsequence of "ABCDE" while "AEC" is not).
Example
Given S = "rabbbit", T = "rabbit", return 3.
@@ -18,29 +25,29 @@ Do it in O(n2) time and O(n) memory.
Attempt2:
Use DP. Okay, first I had no idea how to start, but here is a reference: http://blog.csdn.net/abcbc/article/details/8978146
First of all, Map out the number of existance of T in S in a 2D map:
- 0 1 2 3 4 5 6 7
- ---------------
- r a b b b i t
-0| 1 1 1 1 1 1 1 1
-1| r 0 1 1 1 1 1 1 1
-2| a 0 0 1 1 1 1 1 1
-3| b 0 0 0 1 2 3 3 3
-4| b 0 0 0 0 1 3 3 3
-5| i 0 0 0 0 0 0 3 3
-6| t 0 0 0 0 0 0 0 3
+ 0 1 2 3 4 5 6 7
+ ---------------
+ r a b b b i t
+0| 1 1 1 1 1 1 1 1
+1| r 0 1 1 1 1 1 1 1
+2| a 0 0 1 1 1 1 1 1
+3| b 0 0 0 1 2 3 3 3
+4| b 0 0 0 0 1 3 3 3
+5| i 0 0 0 0 0 0 3 3
+6| t 0 0 0 0 0 0 0 3
Use DP[T][S]. We realize:
1.DP[0][0] == 1; //Both null can be a match
2.DP[0][1 ~ S.length - 1] = 1;//First fow, when T=="", whatever S will have 1 subsequence: ""
3.DP[1 ~ T.length][0] = 0;// First column, when S=="", whatever T will not be subsequence of S == ""
4.When looking at each row and filling out the pixels, we realize when T exist in S[a~b], it will surely exist in S[a~b+1], taht is:
- Step1: DP[i][j] is at least equal to DP[i][j - 1];//DP[i][j] is always based on DP[i][j-1], so DP[i][j] = DP[i][j+1] + something
- Step2: So, what's that 'something' in step1? For example, look at T[3] == 'b' against S[0 ~ 3]:
- S[0 ~ 3] has 1 'b' at S[3], and also, T[0~3] == S[0~3], that's a perfect match. SO DP[3][3] = 1
- S[0 ~ 4] has 2 'b' at S[3] and S[4]. Now imagine we pick either S[3] or S[4] to genreate T[0~3] out of S[0~4]: we have 2 possibilities.D[3][4] = 2
- Consider: D[i][j] means we picked S[j]; in our S[0 ~ 4] case, that means we picked S[4] but skipped S[3], though S[3] still counts towards another situation where we skipped S[4].
- After all, we will count whatever that we skipped into our current DP[i][j], that is DP[i][j] += T[i - 1] == S[j - 1] ? DP[i - 1][j - 1] : 0;
- Conclusion: while we for-looping through each row, if we find out S[j] and S[j - 1] both equals to T[i - 1], we want to make sure we count D[i - 1][j -1]'s previous records in!
+ Step1: DP[i][j] is at least equal to DP[i][j - 1];//DP[i][j] is always based on DP[i][j-1], so DP[i][j] = DP[i][j+1] + something
+ Step2: So, what's that 'something' in step1? For example, look at T[3] == 'b' against S[0 ~ 3]:
+ S[0 ~ 3] has 1 'b' at S[3], and also, T[0~3] == S[0~3], that's a perfect match. SO DP[3][3] = 1
+ S[0 ~ 4] has 2 'b' at S[3] and S[4]. Now imagine we pick either S[3] or S[4] to genreate T[0~3] out of S[0~4]: we have 2 possibilities.D[3][4] = 2
+ Consider: D[i][j] means we picked S[j]; in our S[0 ~ 4] case, that means we picked S[4] but skipped S[3], though S[3] still counts towards another situation where we skipped S[4].
+ After all, we will count whatever that we skipped into our current DP[i][j], that is DP[i][j] += T[i - 1] == S[j - 1] ? DP[i - 1][j - 1] : 0;
+ Conclusion: while we for-looping through each row, if we find out S[j] and S[j - 1] both equals to T[i - 1], we want to make sure we count D[i - 1][j -1]'s previous records in!
Note:
In double for loop, set i,j <= xxxx.length(), since we've increased the 2D array by 1 block on row and col.
@@ -53,23 +60,23 @@ public class Solution {
* @return: Count the number of distinct subsequences
*/
public int numDistinct(String S, String T) {
- int[][] DP = new int[T.length() + 1][S.length() + 1];
- DP[0][0] = 1;
- for(int i = 1; i < S.length(); i++) {
- DP[0][i] = 1;
- }
- for (int i = 1; i < T.length(); i++) {
- DP[i][0] = 0;
- }
- for (int i = 1; i <= T.length(); i++) {
- for (int j = 1; j <= S.length(); j++){
- DP[i][j] = DP[i][j - 1];
- if (T.charAt(i - 1) == S.charAt(j - 1)) {
- DP[i][j] += DP[i - 1][j - 1];
- }
- }
- }
- return DP[T.length()][S.length()];
+ int[][] DP = new int[T.length() + 1][S.length() + 1];
+ DP[0][0] = 1;
+ for(int i = 1; i < S.length(); i++) {
+ DP[0][i] = 1;
+ }
+ for (int i = 1; i < T.length(); i++) {
+ DP[i][0] = 0;
+ }
+ for (int i = 1; i <= T.length(); i++) {
+ for (int j = 1; j <= S.length(); j++){
+ DP[i][j] = DP[i][j - 1];
+ if (T.charAt(i - 1) == S.charAt(j - 1)) {
+ DP[i][j] += DP[i - 1][j - 1];
+ }
+ }
+ }
+ return DP[T.length()][S.length()];
}
}
@@ -81,19 +88,19 @@ public int numDistinct(String S, String T) {
*/
public class Solution {
public int numDistinct(String S, String T) {
- if (S.length() == 0) {
- return T.length() == 0 ? 1 : 0;
- }
- if (T.length() == 0) {
- return 1;
- }
- int count = 0;
- for (int i = 0; i < S.length(); i++) {
- if (S.charAt(i) == T.charAt(0)) {
- count += numDistinct(S.substring(i + 1), T.substring(1));
- }
- }
- return count;
+ if (S.length() == 0) {
+ return T.length() == 0 ? 1 : 0;
+ }
+ if (T.length() == 0) {
+ return 1;
+ }
+ int count = 0;
+ for (int i = 0; i < S.length(); i++) {
+ if (S.charAt(i) == T.charAt(0)) {
+ count += numDistinct(S.substring(i + 1), T.substring(1));
+ }
+ }
+ return count;
}
}
@@ -107,4 +114,5 @@ public int numDistinct(String S, String T) {
However, time cost on this:
For example I have n missing chars from S.length == m. so I have (m + 1) places where i can insert the n chars. Then it's a mCn problem. This goes up to m!, too much. Not applicapable.
-*/
\ No newline at end of file
+*/
+```
\ No newline at end of file
diff --git a/Java/Edit Distance.java b/Java/Edit Distance.java
old mode 100644
new mode 100755
index 916b78f..d13b9ee
--- a/Java/Edit Distance.java
+++ b/Java/Edit Distance.java
@@ -1,5 +1,11 @@
+M
+
+Not Done
+
+```
/*
-Given two words word1 and word2, find the minimum number of steps required to convert word1 to word2. (each operation is counted as 1 step.)
+Given two words word1 and word2, find the minimum number of steps required to convert word1 to word2.
+(each operation is counted as 1 step.)
You have the following 3 operations permitted on a word:
@@ -27,10 +33,6 @@ DP[i][j] means the steps (edit distance) to take to transfer word1[0 ~ i] to wor
public class Solution {
- /**
- * @param word1 & word2: Two string.
- * @return: The minimum number of steps.
- */
public int minDistance(String word1, String word2) {
if (word1 == null && word2 != null) {
return word2.length();
@@ -56,3 +58,5 @@ public int minDistance(String word1, String word2) {
return DP[word1.length()][word2.length()];
}
}
+
+```
\ No newline at end of file
diff --git a/Java/Encode and Decode Strings.java b/Java/Encode and Decode Strings.java
new file mode 100755
index 0000000..2e9245c
--- /dev/null
+++ b/Java/Encode and Decode Strings.java
@@ -0,0 +1,153 @@
+M
+
+方法1:
+用数字+"#"+string来encode.
+基于我们自己定的规律, 在decode的里面不需要过多地去check error input, assume所有input都是规范的.
+decode就是找"#",然后用"#"前的数字截取后面的string.
+
+
+
+Old Solution:
+Cast character into int. 串联起来, seperate by "LINE".
+handle empty list [], or just null: 要把Null特别mark一下为‘NULL’, 这样decode时才能check到。 adminadmin
+
+
+```
+/*
+Design an algorithm to encode a list of strings to a string. The encoded string is then sent over the network and is decoded back to the original list of strings.
+
+Machine 1 (sender) has the function:
+
+string encode(vector strs) {
+ // ... your code
+ return encoded_string;
+}
+Machine 2 (receiver) has the function:
+vector decode(string s) {
+ //... your code
+ return strs;
+}
+So Machine 1 does:
+
+string encoded_string = encode(strs);
+and Machine 2 does:
+
+vector strs2 = decode(encoded_string);
+strs2 in Machine 2 should be the same as strs in Machine 1.
+
+Implement the encode and decode methods.
+
+Note:
+The string may contain any possible characters out of 256 valid ascii characters. Your algorithm should be generalized enough to work on any possible characters.
+Do not use class member/global/static variables to store states. Your encode and decode algorithms should be stateless.
+Do not rely on any library method such as eval or serialize methods. You should implement your own encode/decode algorithm.
+
+
+Tags: String
+Similar Problems: (E) Count and Say, (M) Serialize and Deserialize Binary Tree
+
+*/
+
+
+/*
+Recap 3.28.2016
+Use number+"#" to mark a string. Append them all.
+*/
+public class Codec {
+
+ // Encodes a list of strings to a single string.
+ public String encode(List strs) {
+ if (strs.size() == 0) {
+ return "";
+ }
+ StringBuffer sb = new StringBuffer();
+ for (int i = 0; i < strs.size(); i++) {
+ sb.append(strs.get(i).length() + "#" + strs.get(i));
+ }
+ return sb.toString();
+ }
+
+ // Decodes a single string to a list of strings.
+ public List decode(String s) {
+ List strs = new ArrayList();
+ if (s == null || s.length() == 0) {
+ return strs;
+ }
+ int start = 0;
+ while (start < s.length()) {
+ int ind = s.indexOf("#", start);
+ int leng = Integer.parseInt(s.substring(start, ind));
+
+ start = ind + 1 + leng;
+ strs.add(s.substring(ind + 1, start));
+
+ }
+ return strs;
+ }
+}
+
+
+/*
+Thoughts:
+Break into integers
+Use some special words to: 1. break line. 2. record null condition.
+Note: "" empty string is also a string case, so don't treat that as null. Call null, "NULL"
+Note2: As long as the list is not empty, though some string might be just "", make sure to encode it as 'LINE' just to remind in decoder: treat it as a ""
+*/
+public class Codec {
+ // Encodes a list of strings to a single string.
+ public static String encode(List strs) {
+ if (strs == null || strs.size() == 0) {
+ return "NULL";
+ }
+ StringBuffer sb = new StringBuffer();
+ for (String str : strs) {
+ char[] arr = str.toCharArray();
+ for (int i = 0; i < arr.length; i++) {
+ if (arr[i] >= 100) {
+ sb.append("" + (int)arr[i]);
+ } else if (arr[i] >= 10) {
+ sb.append("0" + (int)arr[i]);
+ } else {
+ sb.append("00" + (int)arr[i]);
+ }
+ }
+ sb.append("LINE");
+ }//END for
+ if (sb.length() == 0) {
+ sb.append("LINE");
+ }
+ return sb.toString();
+ }
+
+ // Decodes a single string to a list of strings.
+ public static List decode(String s) {
+ List rst = new ArrayList();
+ if (s.equals("NULL")) {
+ return rst;
+ }
+ int index = s.indexOf("LINE");
+ while (index != -1) {
+ String str = s.substring(0, index);
+
+ StringBuffer sb = new StringBuffer();
+ int i = 0;
+ while (i + 3 <= str.length()) {
+ int letter = Integer.parseInt(str.substring(i, i + 3));
+ sb.append((char)letter);
+ i+=3;
+ }
+ rst.add(sb.toString());
+
+ s = s.substring(index + 4);
+ index = s.indexOf("LINE");
+ }
+
+ return rst;
+ }
+}
+// Your Codec object will be instantiated and called as such:
+// Codec codec = new Codec();
+// codec.decode(codec.encode(strs));
+
+```
\ No newline at end of file
diff --git a/Java/ExcelSheetColumnNumber .java b/Java/ExcelSheetColumnNumber .java
new file mode 100755
index 0000000..c00c906
--- /dev/null
+++ b/Java/ExcelSheetColumnNumber .java
@@ -0,0 +1,50 @@
+E
+
+'A' - 'A' = 0. 所以 char - 'A' + 1 = 题目里的对应数位。
+26位运算和10位一样嘛,num += 每位的digit * Math.pow(26, 数位号)。
+
+
+```
+/*
+Given a column title as appear in an Excel sheet, return its corresponding column number.
+
+For example:
+
+ A -> 1
+ B -> 2
+ C -> 3
+ ...
+ Z -> 26
+ AA -> 27
+ AB -> 28
+*/
+
+
+public class Solution {//ABC -> 'A', 'B', 'C'
+ public int titleToNumber(String s) {//S = AA
+ int rst = 0;
+ char[] arr = s.toCharArray();
+ for (int i = 0; i < arr.length; i++) {//i = 0,1,2 // (char c : arr)
+ rst = rst * 26 + arr[i] - 'A' + 1;//rst =1, 26 + 1 = 27,
+ }
+ return rst;
+ }
+}
+
+//3.4.2016 recap
+//digit * pow(26, digit position)
+public class Solution {
+ public int titleToNumber(String s) {
+ if (s == null || s.length() == 0) {
+ return 0;
+ }
+ int num = 0;
+ for (int i = s.length() - 1; i >= 0; i--) {
+ int digit = s.charAt(i) - 'A' + 1;
+ num += digit * Math.pow(26, s.length() - i - 1);
+ }
+ return num;
+ }
+}
+
+```
\ No newline at end of file
diff --git a/Java/Expression Evaluation.java b/Java/Expression Evaluation.java
old mode 100644
new mode 100755
index 47df6b5..54aac1e
--- a/Java/Expression Evaluation.java
+++ b/Java/Expression Evaluation.java
@@ -1,10 +1,15 @@
-Build Expression Tree的另外一个变形。
-做的还是PostTraversal。先eval left, right, 然后eval符号。
+H
+
+Build Expression Tree的另外一个变形,依然Min Tree.
+
+build好Min Tree以后,做PostTraversal. Divde and Conquer:
+先recursively找到 left和right的大小, 然后evaluate中间的符号。
+
+Note:
+1. Handle数字时,若left&&right Child全Null,那必定是我们weight最大的数字node了。
+2. 若有个child是null,那就return另外一个node。
+3. prevent Integer overflow during operation:过程中用个Long,最后结局在cast back to int.
-注意Handle数字时,若左右Child全Null,那必定是我们weight最大的数字node了。
-若有个child是null,那就return另外一个node。
-还要注意:
-过程中用个Long吧,最后结局在cast back to int.
```
/*
Given an expression string array, return the final result of this expression
diff --git a/Java/Expression Tree Build.java b/Java/Expression Tree Build.java
old mode 100644
new mode 100755
index 795d3be..544788e
--- a/Java/Expression Tree Build.java
+++ b/Java/Expression Tree Build.java
@@ -1,9 +1,59 @@
+H
+
和Max-tree一样,感谢http://blog.welkinlan.com/2015/06/29/max-tree-lintcode-java/
-这个题目是Min-tree, 头上最小,Logic 和max-tree如出一辙。
-注意虚拟的形态:treeNode,作用就是为了有个weight,好排序。
-要想想,Java这个strict mom,如果换做JavaScript, 直接在expressionTreeNode上面附加一个object就完了,哪还用什么另外一个TreeNode class.
-O(n)
+
+这个题目是Min-tree, 头上最小,Logic 和max-tree如出一辙
+
+注意treeNode,为了帮助ExpressionTreeNode 排序。它加了一个weight based on expression,协助build Min-Tree 排序。
+
+Space: O(n)
+Time on average: O(n).
+
```
+/*
+
+The structure of Expression Tree is a binary tree to evaluate certain expressions.
+All leaves of the Expression Tree have an number string value.
+All non-leaves of the Expression Tree have an operator string value.
+
+Now, given an expression array, build the expression tree of this expression, return the root of this expression tree.
+
+Example
+For the expression (2*6-(23+7)/(1+2)) (which can be represented by ["2" "*" "6" "-" "(" "23" "+" "7" ")" "/" "(" "1" "+" "2" ")"]).
+The expression tree will be like
+
+ [ - ]
+ / \
+ [ * ] [ / ]
+ / \ / \
+ [ 2 ] [ 6 ] [ + ] [ + ]
+ / \ / \
+ [ 23 ][ 7 ] [ 1 ] [ 2 ] .
+After building the tree, you just need to return root node [-].
+
+Clarification
+See wiki:
+Expression Tree
+
+Tags Expand
+LintCode Copyright Stack Binary Tree
+
+
+*/
+
+/**
+ * Definition of ExpressionTreeNode:
+ * public class ExpressionTreeNode {
+ * public String symbol;
+ * public ExpressionTreeNode left, right;
+ * public ExpressionTreeNode(String symbol) {
+ * this.symbol = symbol;
+ * this.left = this.right = null;
+ * }
+ * }
+ */
+
+
public class Solution {
class TreeNode {
int val;
diff --git a/Java/Fast Power.java b/Java/Fast Power.java
old mode 100644
new mode 100755
index dca7b79..385ad5b
--- a/Java/Fast Power.java
+++ b/Java/Fast Power.java
@@ -1,3 +1,15 @@
+M
+
+a^n可以被拆解成(a*a*a*a....*a), 是乘机形式,而%是可以把每一项都mod一下的。所以就拆开来take mod.
+
+这里用个二分的方法,recursively二分下去,直到n/2为0或者1,然后分别对待.
+
+注意1: 二分后要conquer,乘积可能大于Integer.MAX_VALUE, 所以用个long.
+
+注意2: 要处理n%2==1的情况,二分时候自动省掉了一份,要乘一下。
+
+
+```
/*
Calculate the a^n % b where a, b and n are all 32bit integers.
@@ -12,6 +24,10 @@
Tags Expand
Divide and Conquer
+
+*/
+
+/*
Thoughts:
Learn online:
(a * b) % p = (a % p * b % p) % p
@@ -19,27 +35,28 @@
Note: when n is odd number, it cannot be evenly divided into n/2 and n/2. This case needs special treatment: n = n/2 + n/2 + 1;
*/
-
class Solution {
/*
* @param a, b, n: 32bit integers
* @return: An integer
*/
public int fastPower(int a, int b, int n) {
- if (n == 0) {
- return 1 % b;
- }
- if (n == 1) {
- return a % b;
- }
+ if (n == 0) {
+ return 1 % b;
+ }
+ if (n == 1) {
+ return a % b;
+ }
- long recurPow = fastPower(a, b, n / 2);
- recurPow = (recurPow * recurPow) % b;
+ long recurPow = fastPower(a, b, n / 2);
+ recurPow = (recurPow * recurPow) % b;
- if (n % 2 == 1) {
- recurPow = recurPow * a % b;
- }
+ if (n % 2 == 1) {
+ recurPow = recurPow * a % b;
+ }
- return (int)recurPow;
+ return (int)recurPow;
}
};
+
+```
\ No newline at end of file
diff --git a/Java/Fibonacci.java b/Java/Fibonacci.java
old mode 100644
new mode 100755
index adf73eb..237fcbc
--- a/Java/Fibonacci.java
+++ b/Java/Fibonacci.java
@@ -1,3 +1,13 @@
+E
+
+方法1: DP array.
+
+方法1.1: 滚动数组, 简化DP。
+
+方法2: recursively calculate fib(n - 1) + fib(n - 2). 公式没问题, 但是时间太长, timeout.
+
+
+```
/*
Find the Nth number in Fibonacci sequence.
@@ -23,27 +33,65 @@
Tags Expand
Enumeration Mathematics Non Recursion
+
+*/
+/*
+ Recap 3.28.2016.
+ Rolling array, instead of initiating array.
+*/
+class Solution {
+ public int fibonacci(int n) {
+ if (n <= 1) {
+ return 0;
+ }
+ int first = 0;
+ int second = 1;
+ for (int i = 2; i < n; i++) {
+ int temp = second;
+ second = first + second;
+ first = temp;
+ }
+ return second;
+ }
+}
+
+
+/*
Thoughts:
1. If non-recursion, do for loop for that n
2. Note: this specfiic problem is not 0-based. it's 1-based.
3. return fib[n]
*/
-
class Solution {
- /**
- * @param n: an integer
- * @return an integer f(n)
- */
public int fibonacci(int n) {
if (n <= 1) {
- return 0;
+ return 0;
}
- int[] fib = new int[n + 1];
- fib[1] = 0;
- fib[2] = 1;
- for (int i = 3; i <= n; i++) {
- fib[i] = fib[i - 1] + fib[i - 2];
+ int[] fib = new int[n];
+ fib[0] = 0;
+ fib[1] = 1;
+ for (int i = 2; i < n; i++) {
+ fib[i] = fib[i - 1] + fib[i - 2];
}
- return fib[n];
+ return fib[n - 1];
}
}
+
+
+/*
+ Recursive. Long time complexity
+ Timeout
+*/
+class Solution {
+ public int fibonacci(int n) {
+ if (n <= 1) {
+ return 0;
+ }
+ if (n == 2) {
+ return 1;
+ }
+ return fibonacci(n - 1) + fibonacci(n - 2);
+ }
+}
+
+```
\ No newline at end of file
diff --git a/Java/Find the Connected Component in the Undirected Graph.java b/Java/Find the Connected Component in the Undirected Graph.java
index 694d25c..2a8bcc2 100644
--- a/Java/Find the Connected Component in the Undirected Graph.java
+++ b/Java/Find the Connected Component in the Undirected Graph.java
@@ -1,12 +1,15 @@
-BFS遍历,把每个node的neighbor都加进来。
+M
+
+BFS遍历,把每个node的neighbor都加进来。
-一定注意要把visit过的node Mark一下。因为curr node也会是别人的neighbor,会无限循环。
+一定注意要把visit过的node Mark一下。因为curr node也会是别人的neighbor,会无限循环。
-Component的定义:所有Component内的node必须被串联起来via path (反正这里是undirected, 只要链接上就好)
+Component的定义:所有Component内的node必须被串联起来via path (反正这里是undirected, 只要链接上就好)
-这道题:其实component在input里面都已经给好了,所有能一口气visit到的,全部加进queue里面,他们就是一个component里面的了。
+这道题:其实component在input里面都已经给好了,所有能一口气visit到的,全部加进queue里面,他们就是一个component里面的了。
+
+而我们这里不需要判断他们是不是Component。
-而我们这里不需要判断他们是不是Component。
```
/*
Find the number connected component in the undirected graph.
diff --git a/Java/Find the Weak Connected Component in the Directed Graph.java b/Java/Find the Weak Connected Component in the Directed Graph.java
index 34f0384..a898ee7 100644
--- a/Java/Find the Weak Connected Component in the Directed Graph.java
+++ b/Java/Find the Weak Connected Component in the Directed Graph.java
@@ -1,16 +1,19 @@
-Identify这是个union-find问题还挺巧妙。
-看到了weak component的形式: 一个点指向所有,那么所有的点都有一个公共的parent,然后就是要找出这些点。
+M
-为何不能从一个点出发,比如A,直接print它所有的neighbors呢?
- 不行,如果轮到了B点,那因为是directed,它也不知道A的情况,也不知道改如何继续加,或者下手。
+Identify这是个union-find问题还挺巧妙。
+看到了weak component的形式: 一个点指向所有,那么所有的点都有一个公共的parent,然后就是要找出这些点。
-所以,要把所有跟A有关系的点,或者接下去和A的neighbor有关系的点,都放进union-find里面,让这些点有Common parents.
+为何不能从一个点出发,比如A,直接print它所有的neighbors呢?
+ 不行,如果轮到了B点,那因为是directed,它也不知道A的情况,也不知道改如何继续加,或者下手。
+
+所以,要把所有跟A有关系的点,或者接下去和A的neighbor有关系的点,都放进union-find里面,让这些点有Common parents.
+
+最后output的想法:
+做一个 map 。
+之前我们不是给每个num都存好了parent了嘛。
+每个num都有个parent, 然后不同的parent就创造一个不同的list。
+最后,把Map里面所有的list拿出来就好了。
-最后output的想法:
-做一个 map 。
-之前我们不是给每个num都存好了parent了嘛。
-每个num都有个parent, 然后不同的parent就创造一个不同的list。
-最后,把Map里面所有的list拿出来就好了。
```
/*
Find the number Weak Connected Component in the directed graph.
diff --git a/Java/First Bad Version.java b/Java/First Bad Version.java
index 3a13b36..33dc5ad 100644
--- a/Java/First Bad Version.java
+++ b/Java/First Bad Version.java
@@ -1,5 +1,10 @@
-根据isBadVersion的性质,判断还如何end=mid or start=mid.
+M
+
+Binary Search
+
+根据isBadVersion的性质,判断还如何end=mid or start=mid.
isBadVersion 是有方向的嘛,一个点错了,后面全错。
+
```
/*
The code base version is an integer start from 1 to n.
@@ -10,7 +15,7 @@
You can call isBadVersion to help you determine which version is the first bad one.
The details interface can be found in the code's annotation part.
-Have you met this question in a real interview? Yes
+
Example
Given n = 5:
@@ -43,10 +48,6 @@
* the kth code version is bad or not.
*/
class Solution {
- /**
- * @param n: An integers.
- * @return: An integer which is the first bad version.
- */
public int findFirstBadVersion(int n) {
if (n < 1) {
return 0;
diff --git a/Java/Flatten 2D Vector.java b/Java/Flatten 2D Vector.java
new file mode 100644
index 0000000..10cfaee
--- /dev/null
+++ b/Java/Flatten 2D Vector.java
@@ -0,0 +1,82 @@
+/*
+Implement an iterator to flatten a 2d vector.
+
+For example,
+Given 2d vector =
+
+[
+ [1,2],
+ [3],
+ [4,5,6]
+]
+By calling next repeatedly until hasNext returns false, the order of elements returned by next should be: [1,2,3,4,5,6].
+
+Hint:
+
+How many variables do you need to keep track?
+Two variables is all you need. Try with x and y.
+Beware of empty rows. It could be the first few rows.
+To write correct code, think about the invariant to maintain. What is it?
+The invariant is x and y must always point to a valid point in the 2d vector. Should you maintain your invariant ahead of time or right when you need it?
+Not sure? Think about how you would implement hasNext(). Which is more complex?
+Common logic in two different places should be refactored into a common method.
+
+
+Tags: Design
+Similar Problems: (M) Binary Search Tree Iterator, (M) Zigzag Iterator, (M) Peeking Iterator
+
+*/
+
+/*
+Thoughts:
+As hint indicates: use 2 pointers to hold position.
+Use hasNext to validate (x,y) and move x.
+Use next() to return (x,y) and move it(regardless of correctness, which is determined by hasNext())
+*/
+public class Vector2D {
+ private int x;
+ private int y;
+ private List> list;
+ public Vector2D(List> vec2d) {
+ if (vec2d == null) {
+ return;
+ }
+ this.x = 0;
+ this.y = 0;
+ this.list = vec2d;
+ }
+
+ public int next() {
+ int rst = list.get(x).get(y);
+ if (y + 1 >= list.get(x).size()) {
+ y = 0;
+ x++;
+ } else {
+ y++;
+ }
+ return rst;
+ }
+
+ public boolean hasNext() {
+ if (list == null) {
+ return false;
+ }
+ while (x < list.size() && list.get(x).size() == 0) {
+ x++;
+ y = 0;
+ }
+ if (x >= list.size()) {
+ return false;
+ }
+ if (y >= list.get(x).size()) {
+ return false;
+ }
+ return true;
+ }
+}
+
+/**
+ * Your Vector2D object will be instantiated and called as such:
+ * Vector2D i = new Vector2D(vec2d);
+ * while (i.hasNext()) v[f()] = i.next();
+ */
\ No newline at end of file
diff --git a/Java/Flatten Binary Tree to Linked List.java b/Java/Flatten Binary Tree to Linked List.java
index 6ff61e1..88a5acc 100644
--- a/Java/Flatten Binary Tree to Linked List.java
+++ b/Java/Flatten Binary Tree to Linked List.java
@@ -1,3 +1,9 @@
+E
+
+Not Done
+
+
+```
/*
Flatten Binary Tree to Linked List
@@ -48,19 +54,19 @@ public class Solution {
*/
public TreeNode parentNode = null;
public void flatten(TreeNode root) {
- if (root == null) {
- return;
- }
-
- if (parentNode != null) {
- parentNode.left = null;
- parentNode.right = root;
- }
-
- parentNode = root;
- TreeNode right = root.right;
- flatten(root.left);
- flatten(right);
+ if (root == null) {
+ return;
+ }
+
+ if (parentNode != null) {
+ parentNode.left = null;
+ parentNode.right = root;
+ }
+
+ parentNode = root;
+ TreeNode right = root.right;
+ flatten(root.left);
+ flatten(right);
}
}
@@ -80,3 +86,5 @@ public void flatten(TreeNode root) {
+
+```
\ No newline at end of file
diff --git a/Java/Flattern 2D Vector.java b/Java/Flattern 2D Vector.java
new file mode 100644
index 0000000..cc01237
--- /dev/null
+++ b/Java/Flattern 2D Vector.java
@@ -0,0 +1,88 @@
+大概意思就是把2D list里面的element全部遍历一遍。
+注意啊,一开始理解题意搞错:我以为是必须要排序正确,所以上来就PriorityQueue+HashMap搞得无比复杂。其实,这个跟一个nxn的matrix遍历,是没区别的拉。
+所有来个x,y,把2d list跑一变。
+
+```
+/*
+Implement an iterator to flatten a 2d vector.
+
+For example,
+Given 2d vector =
+
+[
+ [1,2],
+ [3],
+ [4,5,6]
+]
+By calling next repeatedly until hasNext returns false, the order of elements returned by next should be: [1,2,3,4,5,6].
+
+Hint:
+
+How many variables do you need to keep track?
+Two variables is all you need. Try with x and y.
+Beware of empty rows. It could be the first few rows.
+To write correct code, think about the invariant to maintain. What is it?
+The invariant is x and y must always point to a valid point in the 2d vector. Should you maintain your invariant ahead of time or right when you need it?
+Not sure? Think about how you would implement hasNext(). Which is more complex?
+Common logic in two different places should be refactored into a common method.
+
+
+Tags: Design
+Similar Problems: (M) Binary Search Tree Iterator, (M) Zigzag Iterator, (M) Peeking Iterator
+
+*/
+
+/*
+Thoughts:
+As hint indicates: use 2 pointers to hold position.
+Use hasNext to validate (x,y) and move x.
+Use next() to return (x,y) and move it(regardless of correctness, which is determined by hasNext())
+*/
+public class Vector2D {
+ private int x;
+ private int y;
+ private List> list;
+ public Vector2D(List> vec2d) {
+ if (vec2d == null) {
+ return;
+ }
+ this.x = 0;
+ this.y = 0;
+ this.list = vec2d;
+ }
+
+ public int next() {
+ int rst = list.get(x).get(y);
+ if (y + 1 >= list.get(x).size()) {
+ y = 0;
+ x++;
+ } else {
+ y++;
+ }
+ return rst;
+ }
+
+ public boolean hasNext() {
+ if (list == null) {
+ return false;
+ }
+ while (x < list.size() && list.get(x).size() == 0) {
+ x++;
+ y = 0;
+ }
+ if (x >= list.size()) {
+ return false;
+ }
+ if (y >= list.get(x).size()) {
+ return false;
+ }
+ return true;
+ }
+}
+
+/**
+ * Your Vector2D object will be instantiated and called as such:
+ * Vector2D i = new Vector2D(vec2d);
+ * while (i.hasNext()) v[f()] = i.next();
+ */
+```
\ No newline at end of file
diff --git a/Java/Flip Game II.java b/Java/Flip Game II.java
new file mode 100644
index 0000000..3fb9bff
--- /dev/null
+++ b/Java/Flip Game II.java
@@ -0,0 +1,171 @@
+12.06.2015 recap:
+注意:不要乱改input s. recursive call 需要用原始的input s.
+
+这个题目李特是屌炸天的。
+我飞了九牛二虎之力(路子对),但是代码写的七荤八素,好长好长好长好长的。
+结果正解,三四行就搞定了。真是心有不甘啊。
+想法如下:
+保证p1能胜利,就必须保持所有p2的move都不能赢。
+同时,p1只要在可走的Move里面,有一个move可以赢就足够了。
+(题目里面用一个for loop + 只要 满足条件就return true来表达 OR的意思:p1不同的路子,赢一种就行了)
+p1: player1
+p2: player2
+
+```
+/*
+You are playing the following Flip Game with your friend:
+Given a string that contains only these two characters: + and -,
+you and your friend take turns to flip two consecutive "++" into "--".
+The game ends when a person can no longer make a move and therefore the other person will be the winner.
+
+Write a function to determine if the starting player can guarantee a win.
+
+For example, given s = "++++", return true. The starting player can guarantee a win by flipping the middle "++" to become "+--+".
+
+Follow up:
+Derive your algorithm's runtime complexity.
+
+Tags: Backtracking
+Similar Problems: (E) Nim Game, (E) Flip Game
+*/
+
+/*
+ recap: 12.06.2015
+ Make sure to use a new string, and do not alter the original input s when calling recursively on canWin.
+*/
+
+public class Solution {
+ public static boolean canWin(String s) {
+ if (s == null || s.length() <= 1) {
+ return false;
+ }
+ String str = new String(s);
+ while (str.indexOf("++") != -1) {
+ int index = str.indexOf("++");
+ if(!canWin(s.substring(0, index) + "--" + s.substring(index + 2))) {
+ return true;
+ }
+ str = str.substring(0, index) + "-" + str.substring(index + 1);
+ }
+ return false;
+ }
+
+}
+
+
+
+/*
+Attemp2, from:http://www.cnblogs.com/jcliBlogger/p/4886741.html
+Similar to my idea, but much more clear: no need of the isP1 flag.
+Iterative idea:p1 can win, and p2 must not win at all.
+Therefore, if p2's move can't win, we return true on p1's state.
+For loop and the if statement works as 'OR': just need one of the p1's movement win.
+*/
+
+public class Solution {
+ public static boolean canWin(String s) {
+ if (s == null || s.length() <= 1) {
+ return false;
+ }
+ String str = new String(s);
+ for (int i = str.indexOf("++"); i >= 0 && i < str.length() - 1; i = str.indexOf("++")) {
+ if (!canWin( s.substring(0, i) + "--" + s.substring(i + 2))) {//Just pick one way of p1's move
+ return true;
+ }
+ str = str.substring(0, i) + "-" + str.substring(i + 1);//Help to move certain spot.
+ }
+ return false;
+ }
+
+}
+//let k = n/2
+//O(k * (k - 1) * (k - 2) ... k) = O(k!) = O((n/2)!) = O(n!)
+
+/*
+Attempt1, Failed.
+Thoughts:
+method checkP1Win(), inside of it:
+OR all p1's win state, if one of the move wins, return true;
+However, a bit of code redundancy, does not feel good about this.
+Fails on "+++++++++"
+*/
+public class Solution {
+ public static boolean canWin(String s) {
+ if (s == null || s.length() <= 1) {
+ return false;
+ }
+ boolean rst = false;
+ String str = new String(s);
+ for (int i = str.indexOf("++"); i >= 0 && i < str.length() - 1; i = str.indexOf("++")) {
+ if (checkP1Win(s, i, true)) {
+ rst = true;
+ break;
+ }
+ str = str.substring(0, i) + "-" + str.substring(i + 1);
+ }
+ return rst;
+
+ }
+ public static boolean checkP1Win(String str, int x, boolean isP1) {
+ String s = str.substring(0,x) + "--" + str.substring(x + 2);
+ if (s.indexOf("++") == -1) {
+ return isP1;
+ }
+ for (int i = s.indexOf("++"); i >= 0 && i < s.length() - 1; i = s.indexOf("++")) {
+ if (checkP1Win(s, i, !isP1)) {
+ return true;
+ }
+ s = s.substring(0, i) + "-" + s.substring(i + 1);
+ }
+ return false;
+ }
+
+
+}
+
+
+
+public class Solution {
+ public static boolean canWin(String s) {
+ if (s == null || s.length() <= 1) {
+ return false;
+ }
+ boolean rst = false;
+ String str = new String(s);
+ for (int i = str.indexOf("++"); i >= 0 && i < str.length() - 1; i = str.indexOf("++")) {
+ if (checkP1Win(s, i, true)) {
+ rst = true;
+ break;
+ }
+ str = str.substring(0, i) + "-" + str.substring(i + 1);
+ }
+ return rst;
+
+ }
+ public static boolean checkP1Win(String str, int x, boolean isP1) {
+ String s = str.substring(0,x) + "--" + str.substring(x + 2);
+ if (s.indexOf("++") == -1) {
+ return isP1;
+ }
+ if (isP1) {
+ String temp = s;
+ for (int i = temp.indexOf("++"); i >= 0 && i < temp.length() - 1; i = temp.indexOf("++")) {
+ if (checkP1Win(s, i, !isP1)) {
+ return true;
+ }
+ temp = temp.substring(0, i) + "-" + temp.substring(i + 1);
+ }
+ return false;
+ } else {
+ String temp = s;
+ for (int i = temp.indexOf("++"); i >= 0 && i < temp.length() - 1; i = temp.indexOf("++")) {
+ if (!checkP1Win(s, i, !isP1)) {
+ return false;
+ }
+ temp = temp.substring(0, i) + "-" + temp.substring(i + 1);
+ }
+ return true;
+ }
+ }
+}
+```
\ No newline at end of file
diff --git a/Java/Flip Game.java b/Java/Flip Game.java
new file mode 100644
index 0000000..2afa5c1
--- /dev/null
+++ b/Java/Flip Game.java
@@ -0,0 +1,78 @@
+这个题目是很寂寞的. 2 pointer可以做, 在网上又搜了一下,貌似可以有很多牛逼的优化,我暂时还没去看。
+很郁闷的就是条件不明,原来只需要从'++'转到'--'的情况,反过来没必要关注...搞了我半天啊
+```
+/*
+You are playing the following Flip Game with your friend: Given a string that contains only these two characters: + and -, you and your friend take turns to flip two consecutive "++" into "--". The game ends when a person can no longer make a move and therefore the other person will be the winner.
+
+Write a function to compute all possible states of the string after one valid move.
+
+For example, given s = "++++", after one move, it may become one of the following states:
+
+[
+ "--++",
+ "+--+",
+ "++--"
+]
+*/
+
+// 12.06.2015, slower than the previous one
+public class Solution {
+ public List generatePossibleNextMoves(String s) {
+ List rst = new ArrayList();
+ if (s == null || s.length() == 0) {
+ return rst;
+ }
+ ArrayList list = new ArrayList();
+ StringBuffer sb = new StringBuffer(s);
+ while (sb.indexOf("++") != -1) {
+ int index = sb.indexOf("++");
+ list.add(index);
+ sb.replace(index, index + 1, "*");
+ }
+ for (int index : list) {
+ rst.add(s.substring(0, index) + "--" + s.substring(index + 2));
+ }
+ return rst;
+ }
+}
+
+
+/*
+Thoughts:
+Two pointers to check if p1 and p2 match target patern. If so, add.
+
+Need to ask: are we only looking to change to '--' from '++'?
+*/
+public class Solution {
+ public static List generatePossibleNextMoves(String s) {
+ List rst = new ArrayList();
+ if (s == null || s.length() < 1) {
+ return rst;
+ }
+ char[] arr = s.toCharArray();
+ search('+','-',arr,rst);
+ return rst;
+ }
+
+ public static void search(char target, char replace, char[] arr, List rst) {
+ int p1 = 0;
+ int p2 = 1;
+ while (p2 <= arr.length - 1) {
+ if (arr[p1] == target && arr[p2] == target) {
+ arr[p1] = replace;
+ arr[p2] = replace;
+ rst.add(new String(arr));
+ arr[p1] = target;
+ arr[p2] = target;
+ }
+ p1++;
+ p2++;
+ }
+ }
+}
+
+
+
+
+
+```
\ No newline at end of file
diff --git a/Java/Fraction to Recurring Decimal.java b/Java/Fraction to Recurring Decimal.java
new file mode 100644
index 0000000..d482da0
--- /dev/null
+++ b/Java/Fraction to Recurring Decimal.java
@@ -0,0 +1,121 @@
+不难想到处理除法:考虑正负,考虑小数点前后。主要是小数点以后的要着重考虑。
+很容易忽略的是integer的益处。
+```
+/*
+Given two integers representing the numerator and denominator of a fraction, return the fraction in string format.
+
+If the fractional part is repeating, enclose the repeating part in parentheses.
+
+For example,
+
+Given numerator = 1, denominator = 2, return "0.5".
+Given numerator = 2, denominator = 1, return "2".
+Given numerator = 2, denominator = 3, return "0.(6)".
+
+Hide Company Tags Google
+Show Tags
+Hash Table Math
+
+
+*/
+
+/*
+ Thoughts:
+ Divide it into small pieces:
+ 1. d = 0, return null;
+ 2. n = 0 -> 0
+ 3. mark negative. let n = abs(numerator), d = abs(denominator)
+ 4. consider front and end:
+ front = (int)sharp divide
+ end: build hashmap to track if the numerator*10 occurs. Once occurs again, return the remianing.
+ 5. based on sign, return results.
+
+Note:
+Have to take int overflow INT_MAX, INT_MIN....
+*/
+//Optimized code:
+public class Solution {
+ public String fractionToDecimal(int numerator, int denominator) {
+ long nume = Math.abs((long)numerator);
+ long deno = Math.abs((long)denominator);
+ String sign = (numerator < 0) ^ (denominator < 0) ? "-" : "";
+ if (deno == 0) {
+ return "";
+ } else if (nume == 0) {
+ return "0";
+ } else if (nume % deno == 0) {
+ return sign + nume/deno + "";
+ }
+
+ HashMap map = new HashMap();
+ StringBuffer rst = new StringBuffer(sign + nume/deno + ".");
+ long end = nume%deno * 10;//The decimal portion of the value, after decimal point
+ int i = 0;
+ while (end != 0){
+ if (map.containsKey(end)) {
+ rst.insert(rst.indexOf(".") + map.get(end) + 1, "(");
+ rst.append(")");
+ return rst.toString();
+ }
+ rst.append(end/deno);
+ map.put(end, i++);
+ end = (end % deno) * 10;
+ }
+ return rst.toString();
+ }
+}
+
+
+
+//Original working version
+public class Solution {
+ public String fractionToDecimal(int numerator, int denominator) {
+ long nume = Math.abs((long)numerator);
+ long deno = Math.abs((long)denominator);
+ String sign = (numerator < 0) ^ (denominator < 0) ? "-" : "";
+ if (deno == 0) {
+ return "";
+ } else if (nume == 0) {
+ return "0";
+ } else if (nume % deno == 0) {
+ return sign + nume/deno + "";
+ }
+
+ String rst = sign + nume/deno + ".";
+ long end = nume%deno * 10;
+
+ HashMap map = new HashMap();
+ boolean repeat = false;
+ String endRepeat = "";
+ int n = 0;
+ while (true){
+ if (end == 0) {
+ break;
+ } else if (map.containsValue(end)) {
+ repeat = true;
+ break;
+ }
+ map.put(n++, end);
+ end = (end % deno) * 10;
+ }
+
+ for (int i = 0; i < n; i++) {
+ if (repeat && map.get(i) == end) {
+ rst += "(" + map.get(i)/deno;
+ endRepeat = ")";
+ repeat = false;
+ } else {
+ rst += map.get(i)/deno;
+ }
+ }
+
+ return rst + endRepeat;
+ }
+}
+
+
+
+
+
+
+```
\ No newline at end of file
diff --git a/Java/Game of Life.java b/Java/Game of Life.java
new file mode 100644
index 0000000..2799713
--- /dev/null
+++ b/Java/Game of Life.java
@@ -0,0 +1,42 @@
+/*
+According to the Wikipedia's article:
+"The Game of Life, also known simply as Life, is a cellular automaton devised by the British mathematician John Horton Conway in 1970."
+
+Given a board with m by n cells, each cell has an initial state live (1) or dead (0).
+Each cell interacts with its eight neighbors (horizontal, vertical, diagonal) using the following four rules
+(taken from the above Wikipedia article):
+
+Any live cell with fewer than two live neighbors dies, as if caused by under-population.
+Any live cell with two or three live neighbors lives on to the next generation.
+Any live cell with more than three live neighbors dies, as if by over-population..
+Any dead cell with exactly three live neighbors becomes a live cell, as if by reproduction.
+Write a function to compute the next state (after one update) of the board given its current state.
+
+Follow up:
+Could you solve it in-place? Remember that the board needs to be updated at the same time:
+You cannot update some cells first and then use their updated values to update other cells.
+In this question, we represent the board using a 2D array.
+ In principle, the board is infinite, which would cause problems when the active area encroaches the border of the array.
+ How would you address these problems?
+Credits:
+Special thanks to @jianchao.li.fighter for adding this problem and creating all test cases.
+
+Hide Company Tags Google TinyCo
+Hide Tags Array
+Hide Similar Problems (M) Set Matrix Zeroes
+
+*/
+
+/*
+ Thoughts:
+ https://segmentfault.com/a/1190000003819277
+ http://my.oschina.net/Tsybius2014/blog/514447
+ build state machine.
+ take mod of 2 at the end.
+*/
+
+public class Solution {
+ public void gameOfLife(int[][] board) {
+
+ }
+}
\ No newline at end of file
diff --git a/Java/Graph Valid Tree.java b/Java/Graph Valid Tree.java
index 18288cc..aed53f0 100644
--- a/Java/Graph Valid Tree.java
+++ b/Java/Graph Valid Tree.java
@@ -1,8 +1,12 @@
-复习Union-Find的另外一个种形式。
-题目类型:查找2个元素是不是在一个set里面。如果不在,false. 如果在,那就合并成一个set,共享parent.
-存储的关键都是:元素相对的index上存着他的root parent.
+M
+
+复习Union-Find的另外一个种形式。
+题目类型:查找2个元素是不是在一个set里面。如果不在,false. 如果在,那就合并成一个set,共享parent.
+存储的关键都是:元素相对的index上存着他的root parent.
另一个union-find, 用hashmap的:http://www.lintcode.com/en/problem/find-the-weak-connected-component-in-the-directed-graph/
+
+
```
/*
Given n nodes labeled from 0 to n - 1 and a list of undirected edges (each edge is a pair of nodes),
diff --git a/Java/Gray Code.java b/Java/Gray Code.java
new file mode 100644
index 0000000..6c0622d
--- /dev/null
+++ b/Java/Gray Code.java
@@ -0,0 +1,175 @@
+M
+
+题目蛋疼,目前只接受一种结果。
+
+BackTracking + DFS:
+ Recursive helper里每次flip一个 自己/左边/右边. Flip过后还要恢复原样.遍历所有.
+
+曾用法(未仔细验证):
+基本想法就是从一个点开始往一个方向走,每次flip一个bit, 碰壁的时候就回头走。
+
+```
+/*
+
+The gray code is a binary numeral system where two successive values differ in only one bit.
+
+Given a non-negative integer n representing the total number of bits in the code, print the sequence of gray code. A gray code sequence must begin with 0.
+
+For example, given n = 2, return [0,1,3,2]. Its gray code sequence is:
+
+00 - 0
+01 - 1
+11 - 3
+10 - 2
+Note:
+For a given n, a gray code sequence is not uniquely defined.
+
+For example, [0,2,3,1] is also a valid gray code sequence according to the above definition.
+
+For now, the judge is able to judge based on one instance of gray code sequence. Sorry about that.
+
+Hide Company Tags Amazon
+Hide Tags Backtracking
+
+*/
+
+
+//Another solution, 02.10.2016 using DFS
+//generate order, output the numerical value of each binary code. Integer.parseInt("10101", 2).
+//Start with n-bit char[] of 0's. Flip one bit at a time.
+//Recursive helper. char[], index. Flip or not flip. DFS
+
+public class Solution {
+ public List grayCode(int n) {
+ List rst = new ArrayList();
+ if (n < 0) {
+ return rst;
+ } else if (n == 0) {
+ rst.add(0);
+ return rst;
+ }
+ char[] list = new char[n];
+ for (int i = 0; i < n; i++) {
+ list[i] = '0';
+ }
+ helper(rst, list, n - 1);
+
+ return rst;
+ }
+
+ public void helper(List rst, char[] list, int index) {
+
+ rst.add(Integer.parseInt(new String(list), 2));
+
+ //self
+ list[index] = list[index] == '0' ? '1' : '0';
+ int num = Integer.parseInt(new String(list), 2);
+ if (!rst.contains(num)) {
+ helper(rst, list, index);
+ }
+ list[index] = list[index] == '0' ? '1' : '0';
+
+ //left
+ if (index -1 >= 0) {
+ list[index - 1] = list[index - 1] == '0' ? '1' : '0';
+ num = Integer.parseInt(new String(list), 2);
+ if (!rst.contains(num)) {
+ helper(rst, list, index - 1);
+ }
+ list[index - 1] = list[index - 1] == '0' ? '1' : '0';
+ }
+
+ //right
+ if (index + 1 < list.length) {
+ list[index + 1] = list[index + 1] == '0' ? '1' : '0';
+ num = Integer.parseInt(new String(list), 2);
+ if (!rst.contains(num)) {
+ helper(rst, list, index + 1);
+ }
+ list[index + 1] = list[index + 1] == '0' ? '1' : '0';
+ }
+ }
+}
+
+
+/*
+
+Leetcode tags shows backtracking. That should be different approach than what I hvae below:
+
+*/
+
+/*
+
+TRY: My code works for this run-through, however does not fit the OJ yet
+
+0 0 0 [start, noting happend, flip index 0]
+
+0 0 <-1 [move to flip left adjacent]
+
+0 <-1 1 [move to flip left adjacent]
+
+1-> 1 1 [move to flip right adjacent]
+
+1 0-> 1 [move to flip right adjacent]
+
+1 0 <-0 [move to flip left adjacent]
+
+1 <-1 0 [move to flip left adjacent]
+
+0 1 0 [done]
+
+Conclusion: hit the wall and flip the other direction.
+
+Every flip, add integer to list
+
+Convert the char[] to string, then Integer.parse(str, 2) to integer
+
+Simulate the steps:
+
+For example, when n = 3, step = n - 1. It takes 2 steps from right side to reach left side, it hits the wall and turn around.
+
+Now:
+
+1. Initialize char[] and add '000'
+
+2. do for loop on 1 ~ 2^n -2. last step '010' is stepped into, but no further action, so take 2^3 - 1 = 7 steps.
+
+*/
+public class Solution {
+ public List | |