();
+
+ static {
+ ID_TO_NAME_LOGISTICS.put(16L, "中外运速递");
+ ID_TO_NAME_LOGISTICS.put(17L, "E特快");
+ ID_TO_NAME_LOGISTICS.put(18L, "芝麻开门");
+ ID_TO_NAME_LOGISTICS.put(19L, "赛澳递");
+ ID_TO_NAME_LOGISTICS.put(20L, "安能物流");
+ ID_TO_NAME_LOGISTICS.put(21L, "安迅物流");
+ ID_TO_NAME_LOGISTICS.put(22L, "巴伦支快递");
+ ID_TO_NAME_LOGISTICS.put(23L, "北青小红帽");
+ ID_TO_NAME_LOGISTICS.put(24L, "百福东方物流");
+ ID_TO_NAME_LOGISTICS.put(25L, "邦送物流");
+ ID_TO_NAME_LOGISTICS.put(26L, "宝凯物流");
+ ID_TO_NAME_LOGISTICS.put(27L, "百千诚物流");
+ ID_TO_NAME_LOGISTICS.put(28L, "博源恒通");
+ ID_TO_NAME_LOGISTICS.put(29L, "百成大达物流");
+ ID_TO_NAME_LOGISTICS.put(30L, "百世快运");
+ ID_TO_NAME_LOGISTICS.put(31L, "COE(东方快递)");
+ ID_TO_NAME_LOGISTICS.put(32L, "城市100");
+ ID_TO_NAME_LOGISTICS.put(33L, "传喜物流");
+ ID_TO_NAME_LOGISTICS.put(34L, "城际速递");
+ ID_TO_NAME_LOGISTICS.put(35L, "成都立即送");
+ ID_TO_NAME_LOGISTICS.put(36L, "出口易");
+ ID_TO_NAME_LOGISTICS.put(37L, "晟邦物流");
+ ID_TO_NAME_LOGISTICS.put(38L, "DHL快递");
+ ID_TO_NAME_LOGISTICS.put(39L, "DHL");
+ ID_TO_NAME_LOGISTICS.put(40L, "德邦大田物流");
+ ID_TO_NAME_LOGISTICS.put(41L, "东方快递");
+ ID_TO_NAME_LOGISTICS.put(42L, "递四方");
+ ID_TO_NAME_LOGISTICS.put(43L, "大洋物流");
+ ID_TO_NAME_LOGISTICS.put(44L, "店通快递");
+ ID_TO_NAME_LOGISTICS.put(45L, "德创物流");
+ ID_TO_NAME_LOGISTICS.put(46L, "东红物流");
+ ID_TO_NAME_LOGISTICS.put(47L, "D速物流");
+ ID_TO_NAME_LOGISTICS.put(48L, "东瀚物流");
+ ID_TO_NAME_LOGISTICS.put(49L, "达方物流");
+ ID_TO_NAME_LOGISTICS.put(50L, "俄顺达");
+ ID_TO_NAME_LOGISTICS.put(51L, "FedEx快递");
+ ID_TO_NAME_LOGISTICS.put(52L, "飞康达物流");
+ ID_TO_NAME_LOGISTICS.put(53L, "飞豹快递");
+ ID_TO_NAME_LOGISTICS.put(54L, "飞狐快递");
+ ID_TO_NAME_LOGISTICS.put(55L, "凡宇速递");
+ ID_TO_NAME_LOGISTICS.put(56L, "颿达国际");
+ ID_TO_NAME_LOGISTICS.put(57L, "飞远配送");
+ ID_TO_NAME_LOGISTICS.put(58L, "飞鹰物流");
+ ID_TO_NAME_LOGISTICS.put(59L, "风行天下");
+ ID_TO_NAME_LOGISTICS.put(60L, "GATI快递");
+ ID_TO_NAME_LOGISTICS.put(61L, "港中能达物流");
+ ID_TO_NAME_LOGISTICS.put(62L, "共速达");
+ ID_TO_NAME_LOGISTICS.put(63L, "广通速递");
+ ID_TO_NAME_LOGISTICS.put(64L, "广东速腾物流");
+ ID_TO_NAME_LOGISTICS.put(65L, "港快速递");
+ ID_TO_NAME_LOGISTICS.put(66L, "高铁速递");
+ ID_TO_NAME_LOGISTICS.put(67L, "冠达快递");
+ ID_TO_NAME_LOGISTICS.put(68L, "华宇物流");
+ ID_TO_NAME_LOGISTICS.put(69L, "恒路物流");
+ ID_TO_NAME_LOGISTICS.put(70L, "好来运快递");
+ ID_TO_NAME_LOGISTICS.put(71L, "华夏龙物流");
+ ID_TO_NAME_LOGISTICS.put(72L, "海航天天");
+ ID_TO_NAME_LOGISTICS.put(73L, "河北建华");
+ ID_TO_NAME_LOGISTICS.put(74L, "海盟速递");
+ ID_TO_NAME_LOGISTICS.put(75L, "华企快运");
+ ID_TO_NAME_LOGISTICS.put(76L, "昊盛物流");
+ ID_TO_NAME_LOGISTICS.put(77L, "户通物流");
+ ID_TO_NAME_LOGISTICS.put(78L, "华航快递");
+ ID_TO_NAME_LOGISTICS.put(79L, "黄马甲快递");
+ ID_TO_NAME_LOGISTICS.put(80L, "合众速递(UCS)");
+ ID_TO_NAME_LOGISTICS.put(81L, "韩润物流");
+ ID_TO_NAME_LOGISTICS.put(82L, "皇家物流");
+ ID_TO_NAME_LOGISTICS.put(83L, "伙伴物流");
+ ID_TO_NAME_LOGISTICS.put(84L, "红马速递");
+ ID_TO_NAME_LOGISTICS.put(85L, "汇文配送");
+ ID_TO_NAME_LOGISTICS.put(86L, "华赫物流");
+ ID_TO_NAME_LOGISTICS.put(87L, "佳吉物流");
+ ID_TO_NAME_LOGISTICS.put(88L, "佳怡物流");
+ ID_TO_NAME_LOGISTICS.put(89L, "加运美快递");
+ ID_TO_NAME_LOGISTICS.put(90L, "急先达物流");
+ ID_TO_NAME_LOGISTICS.put(91L, "京广速递");
+ ID_TO_NAME_LOGISTICS.put(92L, "晋越快递");
+ ID_TO_NAME_LOGISTICS.put(93L, "捷特快递");
+ ID_TO_NAME_LOGISTICS.put(94L, "久易快递");
+ ID_TO_NAME_LOGISTICS.put(95L, "快捷快递");
+ ID_TO_NAME_LOGISTICS.put(96L, "康力物流");
+ ID_TO_NAME_LOGISTICS.put(97L, "跨越速运");
+ ID_TO_NAME_LOGISTICS.put(98L, "快优达速递");
+ ID_TO_NAME_LOGISTICS.put(99L, "快淘快递");
+ ID_TO_NAME_LOGISTICS.put(100L, "联昊通物流");
+ ID_TO_NAME_LOGISTICS.put(101L, "龙邦速递");
+ ID_TO_NAME_LOGISTICS.put(102L, "乐捷递");
+ ID_TO_NAME_LOGISTICS.put(103L, "立即送");
+ ID_TO_NAME_LOGISTICS.put(104L, "蓝弧快递");
+ ID_TO_NAME_LOGISTICS.put(105L, "乐天速递");
+ ID_TO_NAME_LOGISTICS.put(106L, "民航快递");
+ ID_TO_NAME_LOGISTICS.put(107L, "美国快递");
+ ID_TO_NAME_LOGISTICS.put(108L, "门对门");
+ ID_TO_NAME_LOGISTICS.put(109L, "明亮物流");
+ ID_TO_NAME_LOGISTICS.put(110L, "民邦速递");
+ ID_TO_NAME_LOGISTICS.put(111L, "闽盛快递");
+ ID_TO_NAME_LOGISTICS.put(112L, "麦力快递");
+ ID_TO_NAME_LOGISTICS.put(113L, "能达速递");
+ ID_TO_NAME_LOGISTICS.put(114L, "偌亚奥国际");
+ ID_TO_NAME_LOGISTICS.put(115L, "平安达腾飞");
+ ID_TO_NAME_LOGISTICS.put(116L, "陪行物流");
+ ID_TO_NAME_LOGISTICS.put(117L, "全日通快递");
+ ID_TO_NAME_LOGISTICS.put(118L, "全晨快递");
+ ID_TO_NAME_LOGISTICS.put(119L, "秦邦快运");
+ ID_TO_NAME_LOGISTICS.put(120L, "如风达快递");
+ ID_TO_NAME_LOGISTICS.put(121L, "日昱物流");
+ ID_TO_NAME_LOGISTICS.put(122L, "瑞丰速递");
+ ID_TO_NAME_LOGISTICS.put(123L, "山东海红");
+ ID_TO_NAME_LOGISTICS.put(124L, "盛辉物流");
+ ID_TO_NAME_LOGISTICS.put(125L, "世运快递");
+ ID_TO_NAME_LOGISTICS.put(126L, "盛丰物流");
+ ID_TO_NAME_LOGISTICS.put(127L, "上大物流");
+ ID_TO_NAME_LOGISTICS.put(128L, "三态速递");
+ ID_TO_NAME_LOGISTICS.put(129L, "申通E物流");
+ ID_TO_NAME_LOGISTICS.put(130L, "圣安物流");
+ ID_TO_NAME_LOGISTICS.put(131L, "山西红马甲");
+ ID_TO_NAME_LOGISTICS.put(132L, "穗佳物流");
+ ID_TO_NAME_LOGISTICS.put(133L, "沈阳佳惠尔");
+ ID_TO_NAME_LOGISTICS.put(134L, "上海林道货运");
+ ID_TO_NAME_LOGISTICS.put(135L, "十方通物流");
+ ID_TO_NAME_LOGISTICS.put(136L, "山东广通速递");
+ ID_TO_NAME_LOGISTICS.put(137L, "顺捷丰达");
+ ID_TO_NAME_LOGISTICS.put(138L, "TTNT快递");
+ ID_TO_NAME_LOGISTICS.put(139L, "天地华宇");
+ ID_TO_NAME_LOGISTICS.put(140L, "通和天下");
+ ID_TO_NAME_LOGISTICS.put(141L, "天纵物流");
+ ID_TO_NAME_LOGISTICS.put(142L, "同舟行物流");
+ ID_TO_NAME_LOGISTICS.put(143L, "腾达速递");
+ ID_TO_NAME_LOGISTICS.put(144L, "UC优速快递");
+ ID_TO_NAME_LOGISTICS.put(145L, "万象物流");
+ ID_TO_NAME_LOGISTICS.put(146L, "微特派");
+ ID_TO_NAME_LOGISTICS.put(147L, "万家物流");
+ ID_TO_NAME_LOGISTICS.put(148L, "万博快递");
+ ID_TO_NAME_LOGISTICS.put(149L, "希优特快递");
+ ID_TO_NAME_LOGISTICS.put(150L, "新邦物流");
+ ID_TO_NAME_LOGISTICS.put(151L, "信丰物流");
+ ID_TO_NAME_LOGISTICS.put(152L, "祥龙运通物流");
+ ID_TO_NAME_LOGISTICS.put(153L, "西安城联速递");
+ ID_TO_NAME_LOGISTICS.put(154L, "西安喜来快递");
+ ID_TO_NAME_LOGISTICS.put(155L, "鑫世锐达");
+ ID_TO_NAME_LOGISTICS.put(156L, "鑫通宝物流");
+ ID_TO_NAME_LOGISTICS.put(157L, "运通快递");
+ ID_TO_NAME_LOGISTICS.put(158L, "远成物流");
+ ID_TO_NAME_LOGISTICS.put(159L, "亚风速递");
+ ID_TO_NAME_LOGISTICS.put(160L, "优速快递");
+ ID_TO_NAME_LOGISTICS.put(161L, "亿顺航");
+ ID_TO_NAME_LOGISTICS.put(162L, "越丰物流");
+ ID_TO_NAME_LOGISTICS.put(163L, "源安达快递");
+ ID_TO_NAME_LOGISTICS.put(164L, "原飞航物流");
+ ID_TO_NAME_LOGISTICS.put(165L, "邮政EMS速递");
+ ID_TO_NAME_LOGISTICS.put(166L, "银捷速递");
+ ID_TO_NAME_LOGISTICS.put(167L, "一统飞鸿");
+ ID_TO_NAME_LOGISTICS.put(168L, "宇鑫物流");
+ ID_TO_NAME_LOGISTICS.put(169L, "易通达");
+ ID_TO_NAME_LOGISTICS.put(170L, "邮必佳");
+ ID_TO_NAME_LOGISTICS.put(171L, "一柒物流");
+ ID_TO_NAME_LOGISTICS.put(172L, "音素快运");
+ ID_TO_NAME_LOGISTICS.put(173L, "亿领速运");
+ ID_TO_NAME_LOGISTICS.put(174L, "煜嘉物流");
+ ID_TO_NAME_LOGISTICS.put(175L, "英脉物流");
+ ID_TO_NAME_LOGISTICS.put(176L, "云南中诚");
+ ID_TO_NAME_LOGISTICS.put(177L, "中铁快运");
+ ID_TO_NAME_LOGISTICS.put(178L, "中铁物流");
+ ID_TO_NAME_LOGISTICS.put(179L, "中邮物流");
+ ID_TO_NAME_LOGISTICS.put(180L, "邮政快递");
+ ID_TO_NAME_LOGISTICS.put(181L, "郑州建华");
+ ID_TO_NAME_LOGISTICS.put(182L, "中速快件");
+ ID_TO_NAME_LOGISTICS.put(183L, "中天万运");
+ ID_TO_NAME_LOGISTICS.put(184L, "中睿速递");
+ ID_TO_NAME_LOGISTICS.put(185L, "增益速递");
+ ID_TO_NAME_LOGISTICS.put(186L, "郑州速捷");
+ ID_TO_NAME_LOGISTICS.put(187L, "智通物流");
+
+ // // 把enum中的最初的标准15个快递公司和其它也加进来
+ // LogisticsCompanyEnum[] firstArray = LogisticsCompanyEnum.values();
+ // for (int i = 0; i < firstArray.length; i++) {
+ // ID_TO_NAME_LOGISTICS.put(new Long(firstArray[i].getLogisticsCompanyId()),
+ // firstArray[i].getLogisticsCompanyName());
+ // }
+ }
}
diff --git a/src/main/java/org/wcong/test/algorithm/BinaryTree.java b/src/main/java/org/wcong/test/algorithm/BinaryTree.java
new file mode 100644
index 0000000..04ad07b
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/BinaryTree.java
@@ -0,0 +1,91 @@
+package org.wcong.test.algorithm;
+
+/**
+ * Created by hzwangcong on 2017/2/7.
+ */
+public class BinaryTree {
+
+ private Node root;
+
+ public static void main(String[] args) {
+
+ }
+
+ public void add(int value){
+ if( root == null ){
+ root = new Node();
+ root.value = value;
+ return;
+ }
+ Node last = root;
+ while (true){
+ Node next;
+ if( value < last.value ){
+ next = last.left;
+ if( next == null ){
+ Node newNode = new Node();
+ newNode.value = value;
+ last.left = newNode;
+ }else{
+ last = next;
+ }
+ }else{
+ next = last.right;
+ if( next == null ){
+ Node newNode = new Node();
+ newNode.value = value;
+ last.right = newNode;
+ }else{
+ last = next;
+ }
+ }
+ }
+ }
+
+ DubboLinkedInt binaryTreeToLink() {
+ if( root == null ){
+ return null;
+ }
+ DubboLinkedInt middle = new DubboLinkedInt();
+ middle.value = root.value;
+ recurrentLink(root,middle);
+ DubboLinkedInt first = middle;
+ while (first.left!=null){
+ first = first.left;
+ }
+ return first;
+ }
+
+ private void recurrentLink( Node parentNode,DubboLinkedInt parentInt ){
+ if( parentNode.left != null ){
+ DubboLinkedInt leftInt = new DubboLinkedInt();
+ leftInt.value = parentNode.left.value;
+ leftInt.right = parentInt;
+ if( parentInt.left != null ) {
+ DubboLinkedInt tempInt = parentInt.left;
+ parentInt.left = leftInt;
+ leftInt.left = tempInt;
+ }
+ recurrentLink(parentNode.left , leftInt);
+ }
+ if( parentNode.right != null ){
+ DubboLinkedInt rightInt = new DubboLinkedInt();
+ rightInt.value = parentNode.right.value;
+ rightInt.left = parentInt;
+ if(parentInt.right != null) {
+ DubboLinkedInt tempInt = parentInt.right;
+ parentInt.right = rightInt;
+ rightInt.right = tempInt;
+ }
+ recurrentLink(parentNode.right, rightInt);
+ }
+ }
+
+ public static class Node {
+ public int value;
+
+ public Node left;
+
+ public Node right;
+ }
+}
diff --git a/src/main/java/org/wcong/test/algorithm/ContainerWithMostWater.java b/src/main/java/org/wcong/test/algorithm/ContainerWithMostWater.java
new file mode 100644
index 0000000..8ebdc5e
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/ContainerWithMostWater.java
@@ -0,0 +1,41 @@
+package org.wcong.test.algorithm;
+
+import org.eclipse.core.runtime.Assert;
+
+/**
+ * Given n non-negative integers a1, a2, ..., an,
+ * where each represents a point at coordinate (i, ai).
+ * n vertical lines are drawn such that the two endpoints of line i is at (i, ai) and (i, 0).
+ * Find two lines, which together with x-axis forms a container, such that the container contains the most water.
+ * Note: You may not slant the container and n is at least 2.
+ * Created by hzwangcong on 2017/3/1.
+ */
+public class ContainerWithMostWater {
+
+ public static void main(String[] args) {
+ Assert.isTrue(maxArea(new int[]{1, 2}) == 1);
+ Assert.isTrue(maxArea(new int[]{1, 2, 1}) == 2);
+ Assert.isTrue(maxArea(new int[]{3, 2, 1, 3}) == 9);
+ }
+
+ /**
+ * go to next element
+ * second height
+ */
+ public static int maxArea(int[] height) {
+ int left = 0, right = height.length - 1;
+ int maxArea = 0;
+
+ while (left < right) {
+ maxArea = Math.max(maxArea, Math.min(height[left], height[right])
+ * (right - left));
+ if (height[left] < height[right])
+ left++;
+ else
+ right--;
+ }
+
+ return maxArea;
+ }
+
+}
diff --git a/src/main/java/org/wcong/test/algorithm/DubboLinkedInt.java b/src/main/java/org/wcong/test/algorithm/DubboLinkedInt.java
new file mode 100644
index 0000000..9ade03a
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/DubboLinkedInt.java
@@ -0,0 +1,14 @@
+package org.wcong.test.algorithm;
+
+/**
+ * Created by hzwangcong on 2017/2/7.
+ */
+public class DubboLinkedInt {
+
+ int value;
+
+ DubboLinkedInt left;
+
+ DubboLinkedInt right;
+
+}
diff --git a/src/main/java/org/wcong/test/algorithm/HeapSort.java b/src/main/java/org/wcong/test/algorithm/HeapSort.java
new file mode 100644
index 0000000..f3d38fa
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/HeapSort.java
@@ -0,0 +1,35 @@
+package org.wcong.test.algorithm;
+
+/**
+ * a*b,b*c,c*d,d*e
+ *
+ * Created by hzwangcong on 2017/2/5.
+ */
+public class HeapSort {
+
+ public static void main(String[] args) {
+
+ }
+
+ static void maxHeapify(int[] array, int top) {
+ if (top >= array.length) {
+ return;
+ }
+ int left = (top + 1) * 2 - 1;
+ int right = (top + 1) * 2;
+ int large = top;
+ if (left < array.length && array[left] > array[large]) {
+ large = left;
+ }
+ if (right < array.length && array[right] > array[large]) {
+ large = right;
+ }
+ if (large != top) {
+ int temp = array[top];
+ array[top] = array[large];
+ array[large] = temp;
+ maxHeapify(array, large);
+ }
+ }
+
+}
diff --git a/src/main/java/org/wcong/test/algorithm/LongPrefix.java b/src/main/java/org/wcong/test/algorithm/LongPrefix.java
new file mode 100644
index 0000000..772f1b8
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/LongPrefix.java
@@ -0,0 +1,14 @@
+package org.wcong.test.algorithm;
+
+/**
+ * Write a function to find the longest common prefix string amongst an array of strings.
+ * Created by hzwangcong on 2017/3/1.
+ */
+public class LongPrefix {
+
+ public static void main(String[] args) {
+
+ }
+
+
+}
diff --git a/src/main/java/org/wcong/test/algorithm/RBTree.java b/src/main/java/org/wcong/test/algorithm/RBTree.java
new file mode 100644
index 0000000..da0544d
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/RBTree.java
@@ -0,0 +1,10 @@
+package org.wcong.test.algorithm;
+
+/**
+ * Created by hzwangcong on 2017/2/6.
+ */
+public class RBTree {
+ public static void main(String[] args) {
+
+ }
+}
diff --git a/src/main/java/org/wcong/test/algorithm/StringMatch.java b/src/main/java/org/wcong/test/algorithm/StringMatch.java
new file mode 100644
index 0000000..7457d52
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/StringMatch.java
@@ -0,0 +1,83 @@
+package org.wcong.test.algorithm;
+
+import org.eclipse.core.runtime.Assert;
+
+/**
+ * . means anyone char
+ * * means none or many preceding
+ * Created by hzwangcong on 2017/2/14.
+ */
+public class StringMatch {
+
+ public static void main(String[] args) {
+ Assert.isTrue(matchPart("abcd", "c*abcd"));
+ Assert.isTrue(!matchPart("abcdefg", "abcdef*"));
+ Assert.isTrue(matchPart("abcdefg", "abcde.*"));
+ Assert.isTrue(matchPart("abcdefgbcd", "abcde.*cd"));
+ Assert.isTrue(matchPart("aab", "a*b"));
+ Assert.isTrue(matchPart("aaaab", "aa*ab"));
+ Assert.isTrue(matchPart("abcd", ".bcd"));
+ Assert.isTrue(matchPart("abcd", "a.*"));
+ Assert.isTrue(matchPart("a", "ab*"));
+ Assert.isTrue(matchPart("ab", ".*.."));
+ Assert.isTrue(matchPart("abcaaaaaaabaabcabac", ".*ab.a.*a*a*.*b*b*"));
+ }
+
+ static boolean matchPart(String a, String b) {
+ return match(a, b, 0, 0);
+ }
+
+ static boolean match(String a, String b, int aIndex, int bIndex) {
+ while (aIndex < a.length() && bIndex < b.length()) {
+ char aChar = a.charAt(aIndex);
+ char bChar = b.charAt(bIndex);
+ if ((bIndex + 1) < b.length() && b.charAt(bIndex + 1) == '*') {
+ if (bChar == '.') {
+ if ((bIndex + 2) < b.length()) {
+ bChar = b.charAt(bIndex + 2);
+ while (aIndex < a.length()) {
+ if( bChar == '.' && match(a, b, aIndex, bIndex + 2) ){
+ return true;
+ }
+ aChar = a.charAt(aIndex);
+ if (aChar == bChar && match(a, b, aIndex, bIndex + 2)) {
+ return true;
+ }
+ aIndex += 1;
+ }
+ } else {
+ return true;
+ }
+ } else {
+ if (aChar == bChar) {
+ while (aIndex < a.length() && aChar == a.charAt(aIndex)) {
+ if (match(a, b, aIndex, bIndex + 2)) {
+ return true;
+ }
+ aIndex += 1;
+ }
+ }
+ bIndex += 2;
+ continue;
+ }
+ } else if (bChar == '.') {
+ bIndex += 1;
+ aIndex += 1;
+ continue;
+ } else if (aChar == bChar) {
+ bIndex += 1;
+ aIndex += 1;
+ continue;
+ }
+ return false;
+ }
+ while (bIndex < b.length()) {
+ if ((bIndex + 1) < b.length() && b.charAt(bIndex + 1) == '*') {
+ bIndex += 2;
+ } else {
+ break;
+ }
+ }
+ return aIndex == a.length() && bIndex == b.length();
+ }
+}
diff --git a/src/main/java/org/wcong/test/algorithm/SumFor3.java b/src/main/java/org/wcong/test/algorithm/SumFor3.java
new file mode 100644
index 0000000..d6fff49
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/SumFor3.java
@@ -0,0 +1,123 @@
+package org.wcong.test.algorithm;
+
+import org.eclipse.core.runtime.Assert;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * 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.
+ * Note: The solution set must not contain duplicate triplets.
+ * For example, given array S = [-1, 0, 1, 2, -1, -4],
+ * A solution set is:
+ * [
+ * [-1, 0, 1],
+ * [-1, -1, 2]
+ * ]
+ *
+ * Created by hzwangcong on 2017/3/1.
+ */
+public class SumFor3 {
+
+ public static void main(String[] args) {
+
+ Assert.isTrue(listListEqual(treeSum(new int[]{-1, 0, 1, 2, -1, -4}), new ArrayList>(Arrays.asList(Arrays.asList(-1, 0, 1), Arrays.asList(-1, -1, 2)))));
+ }
+
+ private static boolean listListEqual(List> answerList, List> sumArrays) {
+ Iterator> answerIterator = answerList.iterator();
+ while (answerIterator.hasNext()) {
+ List answer = answerIterator.next();
+ Iterator> sumIterator = sumArrays.iterator();
+ while (sumIterator.hasNext()) {
+ List sum = sumIterator.next();
+ if (listEqual(answer, sum)) {
+ sumIterator.remove();
+ answerIterator.remove();
+ break;
+ }
+ }
+ }
+ return answerList.isEmpty() && sumArrays.isEmpty();
+ }
+
+ private static boolean listEqual(List a, List b) {
+ List aTemp = new ArrayList<>(a);
+ List bTemp = new ArrayList<>(b);
+ Iterator aIterator = aTemp.iterator();
+ while (aIterator.hasNext()) {
+ Integer aItem = aIterator.next();
+ Iterator bIterator = bTemp.iterator();
+ while (bIterator.hasNext()) {
+ Integer bItem = bIterator.next();
+ if (aItem.equals(bItem)) {
+ bIterator.remove();
+ aIterator.remove();
+ break;
+ }
+ }
+ }
+ return aTemp.isEmpty() && bTemp.isEmpty();
+ }
+
+
+ public static List> treeSum(int[] nums) {
+ List positiveSet = new ArrayList<>();
+ List negativeSet = new ArrayList<>();
+ int zeroNum = 0;
+ for (int i = 0; i < nums.length; i++) {
+ if (nums[i] == 0) {
+ zeroNum += 1;
+ } else if (nums[i] < 0) {
+ negativeSet.add(-nums[i]);
+ } else {
+ positiveSet.add(nums[i]);
+ }
+ }
+ List> sumList = new ArrayList<>();
+ if (zeroNum > 0) {
+ if (zeroNum > 2) {
+ List oneSum = new ArrayList<>(3);
+ oneSum.add(0);
+ oneSum.add(0);
+ oneSum.add(0);
+ sumList.add(oneSum);
+ }
+ for (Integer positive : positiveSet) {
+ if (negativeSet.contains(positive)) {
+ List oneSum = new ArrayList<>(3);
+ oneSum.add(0);
+ oneSum.add(positive);
+ oneSum.add(-positive);
+ sumList.add(oneSum);
+ }
+ }
+ }
+ sumList.addAll(sumInTwo(positiveSet, negativeSet, true));
+ sumList.addAll(sumInTwo(negativeSet, positiveSet, false));
+ return sumList;
+ }
+
+ private static List> sumInTwo(List positiveSet, List negativeSet, boolean positive) {
+ List> sumList = new ArrayList<>();
+ Integer[] nums = positiveSet.toArray(new Integer[positiveSet.size()]);
+ for (int i = 0; i < nums.length; i++) {
+ for (int j = i + 1; j < nums.length; j++) {
+ int sum = nums[i] + nums[j];
+ if (negativeSet.contains(sum)) {
+ List oneSum = new ArrayList<>(3);
+ oneSum.add(positive ? nums[i] : -nums[i]);
+ oneSum.add(positive ? nums[j] : -nums[j]);
+ oneSum.add(positive ? -sum : sum);
+ sumList.add(oneSum);
+ }
+ }
+ }
+ return sumList;
+ }
+
+
+}
diff --git a/src/main/java/org/wcong/test/algorithm/ThreeSumClosed.java b/src/main/java/org/wcong/test/algorithm/ThreeSumClosed.java
new file mode 100644
index 0000000..8463cd2
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/ThreeSumClosed.java
@@ -0,0 +1,14 @@
+package org.wcong.test.algorithm;
+
+/**
+ * dasdsaadsaasdsasadsdss
+ * Created by hzwangcong on 2017/3/9.
+ */
+public class ThreeSumClosed {
+
+ public static void main(String[] args) {
+
+ }
+
+
+}
diff --git a/src/main/java/org/wcong/test/algorithm/basic/Graph.java b/src/main/java/org/wcong/test/algorithm/basic/Graph.java
new file mode 100644
index 0000000..5eeac42
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/basic/Graph.java
@@ -0,0 +1,48 @@
+package org.wcong.test.algorithm.basic;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * represent a graph
+ * adjacent list
+ * Created by wcong on 2017/3/29.
+ */
+public class Graph {
+
+
+ public static class Edge {
+
+ public Vertex from;
+
+ public Vertex to;
+
+ public int distance;
+
+ }
+
+ public static class Vertex {
+ public int value;
+
+ public int distance;
+
+ public Vertex last;
+
+ @Override
+ public boolean equals(Object o) {
+ if (o == null || !(o instanceof Vertex)) {
+ return false;
+ }
+ return value == ((Vertex) o).value;
+ }
+ }
+
+ public List edges;
+
+ public Map> adjacentMap;
+
+ public void addEdge(Edge edge) {
+ edges.add(edge);
+ adjacentMap.get(edge.from).add(edge.to);
+ }
+}
diff --git a/src/main/java/org/wcong/test/algorithm/basic/Heap.java b/src/main/java/org/wcong/test/algorithm/basic/Heap.java
new file mode 100644
index 0000000..0b430ef
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/basic/Heap.java
@@ -0,0 +1,105 @@
+package org.wcong.test.algorithm.basic;
+
+import java.util.Arrays;
+
+/**
+ * a heap data structure
+ * 1 property max-heap there is max-heap property and min-heap there is min-heap property
+ * 2 operation
+ * 1. max-heapify : give a index,assume it's children is all satisfied ,make sure index is satisfied
+ * 2. build max-heap : make self a max-heap
+ * 3. heap-sort
+ * 4. max-heap-insert
+ * 5. heap-extract-max
+ * 6. heap-increase-key
+ * 7. heap-maximum
+ * Created by wcong on 2017/3/29.
+ */
+public class Heap {
+
+ private int[] array;
+
+ public Heap(int[] array) {
+ assert array != null;
+ this.array = Arrays.copyOf(array, array.length);
+ }
+
+ /**
+ * initialization:priory to the first iteration of loop,i=[n/2],each node[n/2]+1,[n/2]+2,n is a leaf and thus the root
+ */
+ public void buildMaxHeap() {
+ if (array == null || array.length <= 1) {
+ return;
+ }
+ int end = array.length / 2;
+ for (int i = end - 1; i >= 0; i++) {
+ maxHeapify(i, array.length - 1);
+ }
+ }
+
+ public int maximun() {
+ return array[0];
+ }
+
+ public int heapExtractMax() {
+ return 0;
+ }
+
+ public void maxHeapInsert(int add) {
+ int[] newArray = new int[array.length + 1];
+ for (int i = 0; i < array.length; i++) {
+ newArray[i] = array[i];
+ }
+ heapIncreaseKey(newArray.length - 1, add);
+ }
+
+
+ public void heapIncreaseKey(int index, int k) {
+ array[index] = k;
+ while (index > 0) {
+ int parent = (index + 1) / 2 - 1;
+ if (array[parent] < array[index]) {
+ int temp = array[parent];
+ array[parent] = array[index];
+ array[index] = temp;
+ index = parent;
+ } else {
+ break;
+ }
+ }
+ }
+
+ public void maxHeapify(int index, int length) {
+ int left = index * 2 + 1;
+ int right = left + 1;
+ int maxIndex = index;
+ if (left <= length && array[left] > array[maxIndex]) {
+ maxIndex = left;
+ }
+ if (right <= length && array[right] > array[maxIndex]) {
+ maxIndex = right;
+ }
+ if (maxIndex == index) {
+ return;
+ }
+ int temp = array[index];
+ array[index] = array[maxIndex];
+ array[maxIndex] = temp;
+ maxHeapify(maxIndex, length);
+ }
+
+ public static void heapSort(int[] array) {
+ Heap heap = new Heap(array);
+ heap.buildMaxHeap();
+ int end = array.length - 1;
+ while (end > 0) {
+ int temp = array[0];
+ array[0] = array[end];
+ array[end] = temp;
+ end -= 1;
+ heap.maxHeapify(0, end);
+ }
+ }
+
+
+}
diff --git a/src/main/java/org/wcong/test/algorithm/basic/LinkedList.java b/src/main/java/org/wcong/test/algorithm/basic/LinkedList.java
new file mode 100644
index 0000000..880d73f
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/basic/LinkedList.java
@@ -0,0 +1,22 @@
+package org.wcong.test.algorithm.basic;
+
+/**
+ * @author wcong
+ * @since 17/04/2017
+ */
+public class LinkedList {
+
+ public Node root;
+
+ public static class Node {
+
+ public int value;
+
+ public Node next;
+
+ public String toString() {
+ return String.valueOf(value);
+ }
+ }
+
+}
diff --git a/src/main/java/org/wcong/test/algorithm/basic/MinimumSpanningTree.java b/src/main/java/org/wcong/test/algorithm/basic/MinimumSpanningTree.java
new file mode 100644
index 0000000..3b5b580
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/basic/MinimumSpanningTree.java
@@ -0,0 +1,59 @@
+package org.wcong.test.algorithm.basic;
+
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.List;
+import java.util.PriorityQueue;
+import java.util.Queue;
+import java.util.Set;
+
+/**
+ * test for graph
+ * Created by wcong on 2017/3/29.
+ */
+public class MinimumSpanningTree {
+
+
+ public List kruskal(Graph graph) {
+ List mini = new ArrayList<>();
+ Set vertexSet = new HashSet<>();
+ Queue priorityQueue = new PriorityQueue<>(graph.edges.size(), new Comparator() {
+ @Override
+ public int compare(Graph.Edge o1, Graph.Edge o2) {
+ return o2.distance - o1.distance;
+ }
+ });
+ priorityQueue.addAll(graph.edges);
+ while (!priorityQueue.isEmpty()) {
+ Graph.Edge edge = priorityQueue.poll();
+ if (!(vertexSet.contains(edge.from) && vertexSet.contains(edge.to))) {
+ mini.add(edge);
+ vertexSet.add(edge.from);
+ vertexSet.add(edge.to);
+ }
+ }
+ return mini;
+ }
+
+ public List prim(Graph graph) {
+ PriorityQueue priorityQueue = new PriorityQueue<>(graph.adjacentMap.keySet().size(), new Comparator() {
+ @Override
+ public int compare(Graph.Vertex o1, Graph.Vertex o2) {
+ return o2.distance - o1.distance;
+ }
+ });
+ for (Graph.Vertex vertex : graph.adjacentMap.keySet()) {
+ vertex.distance = Integer.MAX_VALUE;
+ priorityQueue.add(vertex);
+ }
+ Graph.Vertex first = priorityQueue.poll();
+ first.distance = 0;
+ priorityQueue.add(first);
+ while (!priorityQueue.isEmpty()) {
+ Graph.Vertex min = priorityQueue.poll();
+
+ }
+ return null;
+ }
+}
diff --git a/src/main/java/org/wcong/test/algorithm/cracking/FirstCommonAncestor.java b/src/main/java/org/wcong/test/algorithm/cracking/FirstCommonAncestor.java
new file mode 100644
index 0000000..8e64d51
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/cracking/FirstCommonAncestor.java
@@ -0,0 +1,50 @@
+package org.wcong.test.algorithm.cracking;
+
+import org.wcong.test.algorithm.tree.BinaryTree;
+
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * Created by wcong on 2017/4/14.
+ */
+public class FirstCommonAncestor {
+
+ public static void main(String[] args) {
+
+ }
+
+ public static BinaryTree.Node firstCommonAncestor(BinaryTree.Node root, BinaryTree.Node target1, BinaryTree.Node target2) {
+ List> resultList = new ArrayList<>(2);
+ List trace = new LinkedList<>();
+ firstCommonAncestor(root, target1, target2, resultList, trace);
+ List pathOne = resultList.get(0);
+ List pathTwo = resultList.get(1);
+ return null;
+ }
+
+ private static void firstCommonAncestor(BinaryTree.Node root,
+ BinaryTree.Node target1,
+ BinaryTree.Node target2,
+ List> resultList,
+ List trace) {
+ if (resultList.size() == 2) {
+ return;
+ }
+ trace.add(root);
+ if (target1.key == root.key) {
+ resultList.add(new LinkedList<>(trace));
+ } else if (target2.key == root.key) {
+ resultList.add(new LinkedList<>(trace));
+ }
+ if (root.left != null) {
+ firstCommonAncestor(root.left, target1, target2, resultList, trace);
+ }
+ if (root.right != null) {
+ firstCommonAncestor(root.right, target1, target2, resultList, trace);
+ }
+ trace.remove(trace.size() - 1);
+ }
+
+}
diff --git a/src/main/java/org/wcong/test/algorithm/cracking/Successor.java b/src/main/java/org/wcong/test/algorithm/cracking/Successor.java
new file mode 100644
index 0000000..59267ba
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/cracking/Successor.java
@@ -0,0 +1,30 @@
+package org.wcong.test.algorithm.cracking;
+
+import org.wcong.test.algorithm.tree.BinaryTree;
+
+/**
+ * Created by wcong on 2017/4/14.
+ */
+public class Successor {
+
+ public static void main(String[] args) {
+
+ }
+
+ public static BinaryTree.Node successor(BinaryTree.Node root, BinaryTree.Node target) {
+ if (root == null || target == null) {
+ return null;
+ }
+ BinaryTree.Node successor = null;
+ while (root != null) {
+ if (target.key < root.key) {
+ successor = root;
+ root = root.left;
+ } else {
+ root = root.right;
+ }
+ }
+ return successor;
+ }
+
+}
diff --git a/src/main/java/org/wcong/test/algorithm/cracking/ValidateBST.java b/src/main/java/org/wcong/test/algorithm/cracking/ValidateBST.java
new file mode 100644
index 0000000..7492b75
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/cracking/ValidateBST.java
@@ -0,0 +1,46 @@
+package org.wcong.test.algorithm.cracking;
+
+import org.wcong.test.algorithm.tree.BinaryTree;
+
+/**
+ * Created by wcong on 2017/4/14.
+ */
+public class ValidateBST {
+
+ public static void main(String[] args) {
+
+ }
+
+ static class Result {
+ boolean validate = true;
+ int maxForNow = Integer.MIN_VALUE;
+ }
+
+ public static boolean validate(BinaryTree.Node root) {
+ if (root == null) {
+ return true;
+ }
+ Result result = new Result();
+ validate(root, result);
+ return result.validate;
+ }
+
+ public static void validate(BinaryTree.Node root, Result result) {
+ if (root == null) {
+ return;
+ }
+ if (root.left != null) {
+ validate(root.left, result);
+ }
+ if (!result.validate) {
+ return;
+ }
+ if (result.maxForNow > root.key) {
+ result.validate = false;
+ return;
+ }
+ result.maxForNow = root.key;
+ validate(root.right, result);
+ }
+
+}
diff --git a/src/main/java/org/wcong/test/algorithm/cracking/array_and_string/CheckPermutation.java b/src/main/java/org/wcong/test/algorithm/cracking/array_and_string/CheckPermutation.java
new file mode 100644
index 0000000..48eba4f
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/cracking/array_and_string/CheckPermutation.java
@@ -0,0 +1,19 @@
+package org.wcong.test.algorithm.cracking.array_and_string;
+
+/**
+ * give two string write a method to decide if one is permutation of the other
+ *
+ * @author wcong
+ * @since 17/04/2017
+ */
+public class CheckPermutation {
+
+ public static void main(String[] args) {
+
+ }
+
+ public static boolean checkPermutation(String a, String b) {
+ return false;
+ }
+
+}
diff --git a/src/main/java/org/wcong/test/algorithm/cracking/array_and_string/IsUnique.java b/src/main/java/org/wcong/test/algorithm/cracking/array_and_string/IsUnique.java
new file mode 100644
index 0000000..dd16667
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/cracking/array_and_string/IsUnique.java
@@ -0,0 +1,34 @@
+package org.wcong.test.algorithm.cracking.array_and_string;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * implement an algorithm to determine if a string has all unique characters
+ * what if you cannot use additional data structures
+ *
+ * 1. none additional space and cannot change original string O(n2)
+ * 2. none additional space and can change original string O(n log n)
+ * 3. additional space hashMap and O(n)
+ *
+ * @author wcong
+ * @since 17/04/2017
+ */
+public class IsUnique {
+
+ public static void main(String[] args) {
+
+ }
+
+ public boolean isUnique(String string) {
+ Map count = new HashMap<>();
+ for (char inner : string.toCharArray()) {
+ if (count.containsKey(inner)) {
+ return false;
+ }
+ count.put(inner, 1);
+ }
+ return true;
+ }
+
+}
diff --git a/src/main/java/org/wcong/test/algorithm/cracking/array_and_string/PalindromePermutation.java b/src/main/java/org/wcong/test/algorithm/cracking/array_and_string/PalindromePermutation.java
new file mode 100644
index 0000000..c1bd454
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/cracking/array_and_string/PalindromePermutation.java
@@ -0,0 +1,21 @@
+package org.wcong.test.algorithm.cracking.array_and_string;
+
+/**
+ * give a string write a function to check if it is a permutation of a palindrome
+ * a palindrome is a word phrase that has same forward and backward
+ * a permutation is a rearrangement of letters
+ * the palindrome does not need to be limit to just dictionary word
+ *
+ * key only one odd word
+ * 1. hash map count the appearance
+ * 2. binary operate, all exclusive or find the left num,second time,exclusive or other the last result
+ * @author wcong
+ * @since 17/04/2017
+ */
+public class PalindromePermutation {
+
+ public static void main(String[] args){
+ int b = ~1;
+ }
+
+}
diff --git a/src/main/java/org/wcong/test/algorithm/cracking/array_and_string/URLify.java b/src/main/java/org/wcong/test/algorithm/cracking/array_and_string/URLify.java
new file mode 100644
index 0000000..611ab23
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/cracking/array_and_string/URLify.java
@@ -0,0 +1,12 @@
+package org.wcong.test.algorithm.cracking.array_and_string;
+
+/**
+ * Write a method to replace all spaces in a string with '%20
+ * You may assume that the string has sufficient space at the end to hold the additional characters
+ * and that you are given the "true" length of the string.
+ * (Note: If implementing in Java,please use a character array so that you can perform this operation in place.)
+ * @author wcong
+ * @since 17/04/2017
+ */
+public class URLify {
+}
diff --git a/src/main/java/org/wcong/test/algorithm/cracking/dp_divide_conque/BooleanEvaluation.java b/src/main/java/org/wcong/test/algorithm/cracking/dp_divide_conque/BooleanEvaluation.java
new file mode 100644
index 0000000..57e988e
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/cracking/dp_divide_conque/BooleanEvaluation.java
@@ -0,0 +1,21 @@
+package org.wcong.test.algorithm.cracking.dp_divide_conque;
+
+import java.util.List;
+
+/**
+ * given a boolean evaluation consisting of symbol
+ * 0(false),1(true),&(and),|(OR),and ^(XOR) and a desired boolean result Result
+ * implement a function to count the number of ways of parenthesizing the expressions
+ * such that it evaluates to result.
+ * the expression should be fully parenthesized
+ *
+ * @author wcong
+ * @since 19/04/2017
+ */
+public class BooleanEvaluation {
+
+ public int count(String expression, boolean result) {
+ return 0;
+ }
+
+}
diff --git a/src/main/java/org/wcong/test/algorithm/cracking/dp_divide_conque/MagicIndex.java b/src/main/java/org/wcong/test/algorithm/cracking/dp_divide_conque/MagicIndex.java
new file mode 100644
index 0000000..6827ad0
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/cracking/dp_divide_conque/MagicIndex.java
@@ -0,0 +1,42 @@
+package org.wcong.test.algorithm.cracking.dp_divide_conque;
+
+/**
+ * a magic index in an array A[1....n-1] is defined to be index such that A[i]=i
+ * given a sorted array of distinct integers
+ * write a method to find the magic index,if one exist in array an index
+ *
+ * @author wcong
+ * @since 19/04/2017
+ */
+public class MagicIndex {
+
+ public int magicIndexDistinct(int[] array) {
+ int start = 0, end = array.length - 1;
+ while (start < end) {
+ int middle = start + (end - start) / 2;
+ if (array[middle] == middle) {
+ return middle;
+ } else if (array[middle] > middle) {
+ end = middle - 1;
+ } else {
+ start = middle + 1;
+ }
+ }
+ return -1;
+ }
+
+ public int magicIndexNormal(int[] array) {
+ int i = 0;
+ while (i < array.length) {
+ if (array[i] == i) {
+ return i;
+ } else if (array[i] > i) {
+ i += 1;
+ } else {
+ i = array[i] + 1;
+ }
+ }
+ return -1;
+ }
+
+}
diff --git a/src/main/java/org/wcong/test/algorithm/cracking/dp_divide_conque/Parenthesis.java b/src/main/java/org/wcong/test/algorithm/cracking/dp_divide_conque/Parenthesis.java
new file mode 100644
index 0000000..b430924
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/cracking/dp_divide_conque/Parenthesis.java
@@ -0,0 +1,41 @@
+package org.wcong.test.algorithm.cracking.dp_divide_conque;
+
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * implement an algorithm to print all valid combinations of n pairs of parenthesis
+ *
+ * @author wcong
+ * @since 19/04/2017
+ */
+public class Parenthesis {
+
+ public List parenthesis(int n) {
+ String[] combinations = new String[n + 1];
+ combinations[0] = "";
+ for (int i = 1; i <= n; i++) {
+ StringBuilder stringBuilder = new StringBuilder(i * 2);
+ for (int j = 0; j < i; j++) {
+ stringBuilder.append("(");
+ }
+ for (int j = 0; j < i; j++) {
+ stringBuilder.append(")");
+ }
+ combinations[i] = stringBuilder.toString();
+ }
+ List result = new LinkedList<>();
+ parenthesisCombination(combinations, "", n, result);
+ return result;
+ }
+
+ private void parenthesisCombination(String[] combinations, String prefix, int remain, List result) {
+ if (remain == 0) {
+ result.add(prefix);
+ }
+ for (int i = 1; i <= remain; i++) {
+ parenthesisCombination(combinations, prefix + combinations[i], remain - 1, result);
+ }
+ }
+
+}
diff --git a/src/main/java/org/wcong/test/algorithm/cracking/dp_divide_conque/PermutionsWithDuplicates.java b/src/main/java/org/wcong/test/algorithm/cracking/dp_divide_conque/PermutionsWithDuplicates.java
new file mode 100644
index 0000000..ae44d1b
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/cracking/dp_divide_conque/PermutionsWithDuplicates.java
@@ -0,0 +1,63 @@
+package org.wcong.test.algorithm.cracking.dp_divide_conque;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * write a method to compute all permutations of a string are not necessarily unique
+ * but not duplicates
+ *
+ * @author wcong
+ * @since 19/04/2017
+ */
+public class PermutionsWithDuplicates {
+
+ static class Summarise {
+ List singles = new ArrayList<>();
+
+ List duplicate = new ArrayList<>();
+ }
+
+ static class Duplicate {
+ Character character;
+
+ int count;
+
+ public Duplicate(Character character, int count) {
+ this.character = character;
+ this.count = count;
+ }
+ }
+
+ public List duplicates(String a) {
+ Map duplicate = new HashMap<>();
+ for (Character character : a.toCharArray()) {
+ Integer count = duplicate.get(character);
+ if (count == null) {
+ duplicate.put(character, 1);
+ } else {
+ duplicate.put(character, count + 1);
+ }
+ }
+ List result = new LinkedList<>();
+ makePermutations(duplicate, "", a.length(), result);
+ return result;
+ }
+
+ private void makePermutations(Map map, String prefix, int remain, List result) {
+ if (remain == 0) {
+ result.add(prefix);
+ return;
+ }
+ for (Map.Entry entry : map.entrySet()) {
+ int count = entry.getValue();
+ map.put(entry.getKey(), count - 1);
+ makePermutations(map, prefix + entry.getKey(), remain - 1, result);
+ map.put(entry.getKey(), count);
+ }
+ }
+
+}
diff --git a/src/main/java/org/wcong/test/algorithm/cracking/dp_divide_conque/RobotInGrid.java b/src/main/java/org/wcong/test/algorithm/cracking/dp_divide_conque/RobotInGrid.java
new file mode 100644
index 0000000..874a16d
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/cracking/dp_divide_conque/RobotInGrid.java
@@ -0,0 +1,65 @@
+package org.wcong.test.algorithm.cracking.dp_divide_conque;
+
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * imagine a robot sitting on the upper left corner of grid with r rows,and c columns
+ * the robot can move in two directions,right and down
+ * but certain cells are off limits such that robot cannot step on them
+ * design an algorithm to find the path for the robot from top left to bottom right
+ *
+ * @author wcong
+ * @since 19/04/2017
+ */
+public class RobotInGrid {
+
+ static class Step {
+ int x;
+
+ int y;
+
+ public Step(int x, int y) {
+ this.x = x;
+ this.y = y;
+ }
+ }
+
+ public List findPath(int[][] grid) {
+
+ Step[][] step = new Step[grid.length][grid[0].length];
+ step[0][grid[0].length - 1] = new Step(0, 0);
+ for (int y = grid[0].length - 2; y >= 0; y--) {
+ if (step[0][y + 1] != null && grid[0][y] == 1) {
+ step[0][y] = new Step(0, y + 1);
+ }
+ }
+ for (int x = 1; x < grid.length; x++) {
+ if (step[x - 1][grid[0].length - 1] != null && grid[x][grid[0].length - 1] == 1) {
+ step[x][grid[0].length - 1] = new Step(x - 1, grid[0].length - 1);
+ }
+ }
+ for (int x = 1; x < grid.length; x++) {
+ for (int y = grid[0].length - 2; y >= 0; y--) {
+ if (grid[x][y] == 0) {
+ continue;
+ }
+ if (step[x - 1][y] != null) {
+ step[x][y] = new Step(x - 1, y);
+ } else if (step[x][y + 1] != null) {
+ step[x][y] = new Step(x, y + 1);
+ }
+ }
+ }
+ if (step[grid.length - 1][grid[0].length - 1] == null) {
+ return null;
+ }
+ List findStep = new LinkedList<>();
+ Step soloStep = step[grid.length - 1][grid[0].length - 1];
+ while (soloStep != null && soloStep.x != 0 && soloStep.y != 0) {
+ findStep.add(0, soloStep);
+ soloStep = step[soloStep.x][soloStep.y];
+ }
+ return findStep;
+ }
+}
diff --git a/src/main/java/org/wcong/test/algorithm/cracking/dp_divide_conque/TowerOfHanoi.java b/src/main/java/org/wcong/test/algorithm/cracking/dp_divide_conque/TowerOfHanoi.java
new file mode 100644
index 0000000..03dc1b3
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/cracking/dp_divide_conque/TowerOfHanoi.java
@@ -0,0 +1,8 @@
+package org.wcong.test.algorithm.cracking.dp_divide_conque;
+
+/**
+ * @author wcong
+ * @since 19/04/2017
+ */
+public class TowerOfHanoi {
+}
diff --git a/src/main/java/org/wcong/test/algorithm/cracking/dp_divide_conque/TripleStep.java b/src/main/java/org/wcong/test/algorithm/cracking/dp_divide_conque/TripleStep.java
new file mode 100644
index 0000000..873af93
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/cracking/dp_divide_conque/TripleStep.java
@@ -0,0 +1,12 @@
+package org.wcong.test.algorithm.cracking.dp_divide_conque;
+
+/**
+ *
+ * @author wcong
+ * @since 19/04/2017
+ */
+public class TripleStep {
+
+
+
+}
diff --git a/src/main/java/org/wcong/test/algorithm/cracking/graph/BinarySequences.java b/src/main/java/org/wcong/test/algorithm/cracking/graph/BinarySequences.java
new file mode 100644
index 0000000..836fa61
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/cracking/graph/BinarySequences.java
@@ -0,0 +1,53 @@
+package org.wcong.test.algorithm.cracking.graph;
+
+import org.wcong.test.algorithm.BinaryTree;
+
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * give a binary search tree with distinct elements
+ * print all possible arrays that could led to this tree
+ *
+ * @author wcong
+ * @since 18/04/2017
+ */
+public class BinarySequences {
+
+ public static void main(String[] args) {
+
+ }
+
+ public static List> sequences(BinaryTree.Node root) {
+ List> result = new LinkedList<>();
+ List path = new LinkedList<>();
+ List nextList = new LinkedList<>();
+ nextList.add(root);
+ sequences(nextList, path, result);
+ return result;
+ }
+
+ private static void sequences(List nextList, List path,
+ List> result) {
+ if (nextList.isEmpty()) {
+ result.add(path);
+ return;
+ }
+ int i = 0;
+ for (BinaryTree.Node next : nextList) {
+ List soloPath = new LinkedList<>(path);
+ path.add(next);
+ List nextNextList = new LinkedList<>(nextList);
+ nextNextList.remove(i);
+ if (next.left != null) {
+ nextNextList.add(next.left);
+ }
+ if (next.right != null) {
+ nextNextList.add(next.right);
+ }
+ sequences(nextNextList, soloPath, result);
+ i += 1;
+ }
+ }
+
+}
diff --git a/src/main/java/org/wcong/test/algorithm/cracking/graph/BuildOrder.java b/src/main/java/org/wcong/test/algorithm/cracking/graph/BuildOrder.java
new file mode 100644
index 0000000..9d930b2
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/cracking/graph/BuildOrder.java
@@ -0,0 +1,18 @@
+package org.wcong.test.algorithm.cracking.graph;
+
+/**
+ * give a list of project and a list of dependencies(where a list of pairs of project where the second project dependent on the first project)
+ * all the project's dependencies must be built for the project is
+ * find a build order that will build order that allow the projects to be built
+ * if there is no valid order ,return an error
+ *
+ * @author wcong
+ * @since 18/04/2017
+ */
+public class BuildOrder {
+
+ public static void main(String[] args) {
+
+ }
+
+}
diff --git a/src/main/java/org/wcong/test/algorithm/cracking/graph/FirstCommonAncestor.java b/src/main/java/org/wcong/test/algorithm/cracking/graph/FirstCommonAncestor.java
new file mode 100644
index 0000000..e660c88
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/cracking/graph/FirstCommonAncestor.java
@@ -0,0 +1,55 @@
+package org.wcong.test.algorithm.cracking.graph;
+
+import org.wcong.test.algorithm.BinaryTree;
+
+/**
+ * design a algorithm and write code to
+ * find the first common ancestor of two nodes in a binary tree,
+ * avoid store additional node in data structure
+ * 1. has parent link ,it's like two linked list intersection
+ * 2. no parent link like tree traversal
+ *
+ * @author wcong
+ * @since 18/04/2017
+ */
+public class FirstCommonAncestor {
+
+ public static void main(String[] args) {
+ }
+
+ static class Result {
+ BinaryTree.Node node;
+
+ boolean isAncestor;
+
+ public Result(BinaryTree.Node node, boolean isAncestor) {
+ this.node = node;
+ this.isAncestor = isAncestor;
+ }
+ }
+
+ public static Result firstCommonAncestor(BinaryTree.Node root, BinaryTree.Node node1, BinaryTree.Node node2) {
+ if (root == null) {
+ return new Result(null, false);
+ }
+ if (root.value == node1.value && root.value == node2.value) {
+ return new Result(root, false);
+ }
+ Result left = firstCommonAncestor(root.left, node1, node2);
+ if (left.isAncestor) {
+ return left;
+ }
+ Result right = firstCommonAncestor(root.right, node1, node2);
+ if (right.isAncestor) {
+ return right;
+ }
+ if (left.node != null && right.node != null) {
+ return new Result(root, true);
+ } else if (root.value == node1.value || root.value == node2.value) {
+ boolean isAncestor = left.node != null || right.node != null;
+ return new Result(root, isAncestor);
+ } else {
+ return new Result(null, false);
+ }
+ }
+}
diff --git a/src/main/java/org/wcong/test/algorithm/cracking/graph/PathWithSum.java b/src/main/java/org/wcong/test/algorithm/cracking/graph/PathWithSum.java
new file mode 100644
index 0000000..4a7c14e
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/cracking/graph/PathWithSum.java
@@ -0,0 +1,48 @@
+package org.wcong.test.algorithm.cracking.graph;
+
+import org.wcong.test.algorithm.BinaryTree;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * you are given a binary tree which every node contains an integer value(positive or negative)
+ * design an algorithm to count the numbers of path that sum to a given value
+ * the path does need to start or end at the root or leaf but it must go downwards
+ * depth first traversal, it can be solved by a algorithm for count subList sum to a target
+ *
+ * @author wcong
+ * @since 18/04/2017
+ */
+public class PathWithSum {
+
+ public static void main(String[] args) {
+
+ }
+
+ public static int count(BinaryTree.Node root, int target) {
+ return count(root, 0, target, new HashMap());
+ }
+
+ private static int count(BinaryTree.Node root, int sum, int target, Map sumMap) {
+ if (root == null) {
+ return 0;
+ }
+ sum += root.value;
+ int left = target - sum;
+ Integer leftNum = sumMap.get(left);
+ leftNum = leftNum == null ? 0 : leftNum;
+ int count = leftNum;
+ if (sum == target) {
+ count += 1;
+ }
+
+ sumMap.put(sum, sumMap.get(sum) == null ? 1 : sumMap.get(sum) + 1);
+
+ int leftCount = count(root.left, sum, target, sumMap);
+ int rightCount = count(root.right, sum, target, sumMap);
+ sumMap.put(sum, sumMap.get(sum) - 1);
+ return count + leftCount + rightCount;
+ }
+
+}
diff --git a/src/main/java/org/wcong/test/algorithm/cracking/linked_list/DeleteMiddle.java b/src/main/java/org/wcong/test/algorithm/cracking/linked_list/DeleteMiddle.java
new file mode 100644
index 0000000..6f6d587
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/cracking/linked_list/DeleteMiddle.java
@@ -0,0 +1,36 @@
+package org.wcong.test.algorithm.cracking.linked_list;
+
+import org.wcong.test.algorithm.basic.LinkedList;
+
+/**
+ * give a linked list delete the middle node of it
+ *
+ * @author wcong
+ * @since 17/04/2017
+ */
+public class DeleteMiddle {
+
+ public static void main(String[] args) {
+
+ }
+
+ public static void deleteMiddle(LinkedList.Node root) {
+ if (root == null) {
+ return;
+ }
+ LinkedList.Node current = root;
+ LinkedList.Node middle = root;
+ int middleCount = 1;
+ int count = 0;
+ while (current != null) {
+ count += 1;
+ current = current.next;
+ while (middleCount < (count / 2)) {
+ middle = middle.next;
+ middleCount += 1;
+ }
+ }
+ middle.next = middle.next.next;
+ }
+
+}
diff --git a/src/main/java/org/wcong/test/algorithm/cracking/linked_list/LoopDetection.java b/src/main/java/org/wcong/test/algorithm/cracking/linked_list/LoopDetection.java
new file mode 100644
index 0000000..d638543
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/cracking/linked_list/LoopDetection.java
@@ -0,0 +1,44 @@
+package org.wcong.test.algorithm.cracking.linked_list;
+
+import org.wcong.test.algorithm.basic.LinkedList;
+
+/**
+ * given a circle linked list
+ * implement an algorithm that return the node at the beginning of the loop
+ *
+ * @author wcong
+ * @since 17/04/2017
+ */
+public class LoopDetection {
+
+ public static void main(String[] args) {
+
+ }
+
+ public static LinkedList.Node begining(LinkedList.Node list) {
+ LinkedList.Node step1 = list;
+ LinkedList.Node step2 = list;
+ while (true) {
+ if (step1 == null || step2 == null) {
+ return null;
+ }
+ step1 = step1.next;
+ if (step2.next == null) {
+ return null;
+ }
+ step2 = step2.next.next;
+ if (step1 == step2) {
+ break;
+ }
+ }
+ step1 = list;
+ while (true) {
+ if (step1 == step2) {
+ return step1;
+ }
+ step1 = step1.next;
+ step2 = step2.next;
+ }
+ }
+
+}
diff --git a/src/main/java/org/wcong/test/algorithm/cracking/linked_list/Palindrome.java b/src/main/java/org/wcong/test/algorithm/cracking/linked_list/Palindrome.java
new file mode 100644
index 0000000..b0e2bad
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/cracking/linked_list/Palindrome.java
@@ -0,0 +1,57 @@
+package org.wcong.test.algorithm.cracking.linked_list;
+
+import org.wcong.test.algorithm.basic.LinkedList;
+
+/**
+ * implement a function to check if a linked list is palindrome
+ *
+ * @author wcong
+ * @since 17/04/2017
+ */
+public class Palindrome {
+
+ public static void main(String[] args) {
+
+ }
+
+ static class Result {
+ LinkedList.Node node;
+
+ boolean result = true;
+
+ }
+
+ public static boolean isPalindrome(LinkedList.Node root) {
+ int length = length(root);
+ return true;
+ }
+
+ private static Result judge(LinkedList.Node node, int length) {
+ if (length <= 0) {
+ Result result = new Result();
+ result.node = node.next;
+ return result;
+ } else if (length == 1) {
+ Result result = new Result();
+ result.node = node;
+ return result;
+ }
+ Result result = judge(node, length - 2);
+ if (!result.result) {
+ return result;
+ }
+ result.result = node.value == result.node.value;
+ result.node = node.next;
+ return result;
+ }
+
+ public static int length(LinkedList.Node root) {
+ int length = 0;
+ while (root != null) {
+ length += 1;
+ root = root.next;
+ }
+ return length;
+ }
+
+}
diff --git a/src/main/java/org/wcong/test/algorithm/cracking/linked_list/SumList.java b/src/main/java/org/wcong/test/algorithm/cracking/linked_list/SumList.java
new file mode 100644
index 0000000..2789ad8
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/cracking/linked_list/SumList.java
@@ -0,0 +1,13 @@
+package org.wcong.test.algorithm.cracking.linked_list;
+
+/**
+ * @author wcong
+ * @since 17/04/2017
+ */
+public class SumList {
+
+ public static void main(String[] args) {
+
+ }
+
+}
diff --git a/src/main/java/org/wcong/test/algorithm/cracking/sort_and_search/GroupAnagrams.java b/src/main/java/org/wcong/test/algorithm/cracking/sort_and_search/GroupAnagrams.java
new file mode 100644
index 0000000..b884e43
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/cracking/sort_and_search/GroupAnagrams.java
@@ -0,0 +1,45 @@
+package org.wcong.test.algorithm.cracking.sort_and_search;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * write a method to sort an array of strings so that all the anagrams are next to each other
+ *
+ * @author wcong
+ * @since 19/04/2017
+ */
+public class GroupAnagrams {
+
+ public static void main(String[] args) {
+
+ }
+
+ public static String[] groupAnagrams(String[] array) {
+ Map> map = new HashMap<>();
+ for (String solo : array) {
+ char[] charArray = solo.toCharArray();
+ Arrays.sort(charArray);
+ String sortedArray = new String(charArray);
+ List stringList = map.get(sortedArray);
+ if (stringList == null) {
+ stringList = new LinkedList<>();
+ map.put(sortedArray, stringList);
+ }
+ stringList.add(solo);
+ }
+ String[] anagrams = new String[array.length];
+ int index = 0;
+ for (List stringList : map.values()) {
+ for (String solo : stringList) {
+ anagrams[index] = solo;
+ index += 1;
+ }
+ }
+ return anagrams;
+ }
+
+}
diff --git a/src/main/java/org/wcong/test/algorithm/cracking/sort_and_search/MergeSorted.java b/src/main/java/org/wcong/test/algorithm/cracking/sort_and_search/MergeSorted.java
new file mode 100644
index 0000000..89d6a22
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/cracking/sort_and_search/MergeSorted.java
@@ -0,0 +1,42 @@
+package org.wcong.test.algorithm.cracking.sort_and_search;
+
+/**
+ * you are given two sorted arrays A and B
+ * where A has a large enough buffer at the end to hold b
+ * write a method merge B into A in sorted order
+ *
+ * @author wcong
+ * @since 19/04/2017
+ */
+public class MergeSorted {
+
+ public static void main(String[] args) {
+
+ }
+
+ public static void merge(int[] array1, int[] array2) {
+ int length = array1.length + array2.length;
+ int array1Index = array1.length - 1;
+ int array2Index = array2.length - 1;
+ for (int j = length - 1; j >= 0; j--) {
+ if (array1Index < 0 && array2Index < 0) {
+ break;
+ } else if (array1Index < 0) {
+ array1[j] = array2[array2Index];
+ array2Index -= 1;
+ } else if (array2Index < 0) {
+ array1[j] = array1[array1Index];
+ array1Index -= 1;
+ } else {
+ if (array1[array1Index] < array2[array2Index]) {
+ array1[j] = array2[array2Index];
+ array2Index -= 1;
+ } else {
+ array1[j] = array1[array1Index];
+ array1Index -= 1;
+ }
+ }
+ }
+ }
+
+}
diff --git a/src/main/java/org/wcong/test/algorithm/cracking/sort_and_search/SparseSearch.java b/src/main/java/org/wcong/test/algorithm/cracking/sort_and_search/SparseSearch.java
new file mode 100644
index 0000000..41371b2
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/cracking/sort_and_search/SparseSearch.java
@@ -0,0 +1,42 @@
+package org.wcong.test.algorithm.cracking.sort_and_search;
+
+/**
+ * given a sorted array of string that is interspersed with empty string
+ * write a method to find the location of the string
+ *
+ * @author wcong
+ * @since 19/04/2017
+ */
+public class SparseSearch {
+
+ public static void main(String[] args) {
+
+ }
+
+ public static int index(String[] array, String target) {
+ return index(array, target, 0, array.length);
+ }
+
+ private static int index(String[] array, String target, int start, int end) {
+ if (start > end) {
+ return -1;
+ }
+ int middle = start + (end - start) / 2;
+ if (array[middle].length() == 0) {
+ int leftIndex = index(array, target, start, middle - 1);
+ if (leftIndex > 0) {
+ return leftIndex;
+ }
+ return index(array, target, middle + 1, end);
+ } else {
+ if (target.equals(array[middle])) {
+ return middle;
+ } else if (target.compareTo(array[middle]) < 0) {
+ return index(array, target, start, middle - 1);
+ } else {
+ return index(array, target, middle + 1, end);
+ }
+ }
+ }
+
+}
diff --git a/src/main/java/org/wcong/test/algorithm/dp/AllPermutation.java b/src/main/java/org/wcong/test/algorithm/dp/AllPermutation.java
new file mode 100644
index 0000000..45e36f1
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/dp/AllPermutation.java
@@ -0,0 +1,8 @@
+package org.wcong.test.algorithm.dp;
+
+/**
+ * give a string of unique character ,return all permutation
+ * Created by wcong on 2017/3/31.
+ */
+public class AllPermutation {
+}
diff --git a/src/main/java/org/wcong/test/algorithm/dp/BreakingAString.java b/src/main/java/org/wcong/test/algorithm/dp/BreakingAString.java
new file mode 100644
index 0000000..d95e7e4
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/dp/BreakingAString.java
@@ -0,0 +1,30 @@
+package org.wcong.test.algorithm.dp;
+
+/**
+ * given a string S with n characters and an array containing the break points, compute
+ * the lowest cost for a sequence of breaks, along with a sequence of breaks that
+ * achieves this cost.
+ * length of 20 points 2,8,10
+ * Created by wcong on 2017/3/31.
+ */
+public class BreakingAString {
+ public static void main(String[] args) {
+
+ }
+
+ public static int minimumCost(String a, int[] point) {
+ return minimumCost(a, 0, a.length() - 1, point, 0, point.length - 1);
+ }
+
+ public static int minimumCost(String a, int start, int end, int[] point, int pointStart, int pointEnd) {
+ if (start >= end || pointStart >= pointEnd) {
+ return 0;
+ }
+ int length = end - start + 1;
+ int left = minimumCost(a, point[pointStart], end, point, pointStart + 1, pointEnd);
+ int right = minimumCost(a, start, point[pointEnd], point, pointStart, pointEnd - 1);
+ return left < right ? left + length : right + length;
+ }
+
+
+}
diff --git a/src/main/java/org/wcong/test/algorithm/dp/ChangeMaking.java b/src/main/java/org/wcong/test/algorithm/dp/ChangeMaking.java
new file mode 100644
index 0000000..7d20a1a
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/dp/ChangeMaking.java
@@ -0,0 +1,31 @@
+package org.wcong.test.algorithm.dp;
+
+/**
+ * give change for amount n using the minimum number of coin of denomination d1
+ * @since 2017/4/9
+ */
+public class ChangeMaking {
+
+ public static void main(String[] args) {
+
+ }
+
+ public static int minimumNums(int[] array, int amount) {
+ int[] result = new int[amount + 1];
+ result[0] = 0;
+ for (int i = 1; i <= amount; i++) {
+ int min = i;
+ for (int j = 0; j < array.length; j++) {
+ if (array[j] > i) {
+ break;
+ }
+ min = Math.min(min, result[i - array[j]] + 1);
+ }
+ result[i] = min;
+ }
+ return result[amount];
+ }
+
+}
diff --git a/src/main/java/org/wcong/test/algorithm/dp/CoinRow.java b/src/main/java/org/wcong/test/algorithm/dp/CoinRow.java
new file mode 100644
index 0000000..7dddecb
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/dp/CoinRow.java
@@ -0,0 +1,27 @@
+package org.wcong.test.algorithm.dp;
+
+/**
+ * this is a row of n coins whose values are some positive integers c1,c2,....,cn
+ * not necessarily distinct,the goal is to pick up the maximum amount of money subject
+ * that no two coins adjacent in the initial row can be picked up.
+ *
+ * @author wcong
+ * @since 2017/4/9
+ */
+public class CoinRow {
+
+ public static void main(String[] args) {
+
+ }
+
+ public static int maxCoinSum(int[] array) {
+ int[] result = new int[array.length];
+ result[0] = 0;
+ result[1] = array[0];
+ for (int i = 1; i < array.length; i++) {
+ result[i + 1] = Math.max(result[i], result[i - 1] + array[i]);
+ }
+ return result[array.length];
+ }
+
+}
diff --git a/src/main/java/org/wcong/test/algorithm/dp/CoinsCollect.java b/src/main/java/org/wcong/test/algorithm/dp/CoinsCollect.java
new file mode 100644
index 0000000..031c94d
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/dp/CoinsCollect.java
@@ -0,0 +1,27 @@
+package org.wcong.test.algorithm.dp;
+
+/**
+ * give a m*n matrix board each cell is 0 cell or 1 cell,
+ * a robot collect coin from left up
+ * calculate the max coin number when he arrive the right bottom
+ *
+ * @author wcong
+ * @since 2017/4/9
+ */
+public class CoinsCollect {
+
+ public static void main(String[] args) {
+
+ }
+
+ public static int maxCoins(int[][] board) {
+ int[][] result = new int[board.length + 1][board[0].length + 1];
+ for (int i = 0; i < board.length; i++) {
+ for (int j = 0; j < board[0].length; j++) {
+ result[i + 1][j + 1] = Math.max(result[i][j + 1], result[i + 1][j]) + board[i][j];
+ }
+ }
+ return result[board.length][board[0].length];
+ }
+
+}
diff --git a/src/main/java/org/wcong/test/algorithm/dp/EditDistance.java b/src/main/java/org/wcong/test/algorithm/dp/EditDistance.java
new file mode 100644
index 0000000..f3c55de
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/dp/EditDistance.java
@@ -0,0 +1,31 @@
+package org.wcong.test.algorithm.dp;
+
+/**
+ * give two strings a,b calculate the distance for b transform to b
+ * use
+ * add insert one char
+ * delete delete one char
+ * replace replace one char
+ * return the minimum distance
+ * Created by wcong on 2017/3/31.
+ */
+public class EditDistance {
+
+ public static void main() {
+ }
+
+ public static int mininumEditDistance(String a, String b) {
+ int[][] result = new int[a.length()][b.length()];
+ for (int i = 0; i < a.length(); i++) {
+ for (int j = 0; j < b.length(); j++) {
+ if (a.charAt(i) == b.charAt(j)) {
+ result[i + 1][j + 1] = result[i][j] + 1;
+ } else {
+ result[i + 1][j + 1] = 1 + Math.min(Math.min(result[i + 1][j], result[i][j + 1]), result[i][j]);
+ }
+ }
+ }
+ return result[a.length()][b.length()];
+ }
+
+}
diff --git a/src/main/java/org/wcong/test/algorithm/dp/Knapsack.java b/src/main/java/org/wcong/test/algorithm/dp/Knapsack.java
new file mode 100644
index 0000000..a572e28
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/dp/Knapsack.java
@@ -0,0 +1,33 @@
+package org.wcong.test.algorithm.dp;
+
+/**
+ * give n items has weight,w1,w2....,wn and values v1,v2....vn,
+ * we have a bag contains m weight
+ * find the largest value for the bag
+ *
+ * @author wcong
+ * @since 2017/4/9
+ */
+public class Knapsack {
+
+ public static void main(String[] args) {
+
+ }
+
+ public static int maxValue(int[] weight, int[] values, int bag) {
+ int[] result = new int[bag + 1];
+ result[0] = 0;
+ for (int i = 1; i <= bag; i++) {
+ int max = Integer.MIN_VALUE;
+ for (int j = 0; j < weight.length; j++) {
+ if (i < weight[j]) {
+ break;
+ }
+ max = Math.max(values[j] + result[i - weight[j]], max);
+ }
+ result[i] = max;
+ }
+ return result[bag];
+ }
+
+}
diff --git a/src/main/java/org/wcong/test/algorithm/dp/LongestCommonSubSequence.java b/src/main/java/org/wcong/test/algorithm/dp/LongestCommonSubSequence.java
new file mode 100644
index 0000000..bf00be8
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/dp/LongestCommonSubSequence.java
@@ -0,0 +1,41 @@
+package org.wcong.test.algorithm.dp;
+
+/**
+ * give two string a,b find the longest common sub sequence
+ * Created by wcong on 2017/3/31.
+ */
+public class LongestCommonSubSequence {
+
+ public static void main(String[] args) {
+
+ }
+
+ public static int longest(String a, String b) {
+ int[][] result = new int[a.length() + 1][b.length() + 1];
+ if (a.charAt(0) == b.charAt(0)) {
+ result[1][1] = 1;
+ }
+ for (int i = 0; i < b.length(); i++) {
+ if (a.charAt(0) == b.charAt(i)) {
+ result[1][i + 1] = 1;
+ }
+ }
+ for (int i = 1; i < a.length(); i++) {
+ for (int j = 0; j < b.length(); j++) {
+ if (a.charAt(i) == b.charAt(j)) {
+ result[i][j] = result[i - 1][j] + 1;
+ }
+ }
+ }
+ int max = 0;
+ for (int i = 0; i < a.length(); i++) {
+ for (int j = 0; j < b.length(); j++) {
+ if (result[i][j] > max) {
+ max = result[i][j];
+ }
+ }
+ }
+ return max;
+ }
+
+}
diff --git a/src/main/java/org/wcong/test/algorithm/dp/LongestPalindromeSubsequence.java b/src/main/java/org/wcong/test/algorithm/dp/LongestPalindromeSubsequence.java
new file mode 100644
index 0000000..614cca6
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/dp/LongestPalindromeSubsequence.java
@@ -0,0 +1,46 @@
+package org.wcong.test.algorithm.dp;
+
+import org.eclipse.core.runtime.Assert;
+
+/**
+ * give a string find the longest palindrome sub sequence
+ * Created by wcong on 2017/3/31.
+ */
+public class LongestPalindromeSubsequence {
+
+ public static void main(String[] args) {
+ Assert.isTrue(palindrome("cabdbae") == 5);
+ }
+
+ public static int palindrome(String a) {
+ int[][] result = new int[a.length()][a.length()];
+ for (int i = 0; i < a.length(); i++) {
+ result[i][i] = 1;
+ }
+ for (int i = 1; i < a.length(); i++) {
+ for (int j = 0; j < i; j++) {
+ if (a.charAt(i) == a.charAt(j)) {
+ if (i - j - 1 == 1) {
+ result[i][j] = 3;
+ } else if (i - 1 > 0 && j + 1 < i - 1) {
+ if (result[i - 1][j + 1] > 0) {
+ result[i][j] = result[i - 1][j + 1] + 2;
+ }
+ } else {
+ result[i][j] = 1;
+ }
+ }
+ }
+ }
+ int max = 1;
+ for (int i = 0; i < a.length(); i++) {
+ for (int j = 0; j < a.length(); j++) {
+ if (result[i][j] > max) {
+ max = result[i][j];
+ }
+ }
+ }
+ return max;
+ }
+
+}
diff --git a/src/main/java/org/wcong/test/algorithm/dp/MatrixChainMultiplication.java b/src/main/java/org/wcong/test/algorithm/dp/MatrixChainMultiplication.java
new file mode 100644
index 0000000..d459444
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/dp/MatrixChainMultiplication.java
@@ -0,0 +1,40 @@
+package org.wcong.test.algorithm.dp;
+
+/**
+ * we are given a sequence of matrix to to multiplied
+ * and we wish to computer the product
+ * TODO
+ * Created by wcong on 2017/3/30.
+ */
+public class MatrixChainMultiplication {
+
+ static class MatrixSymbol {
+ int row = 1;
+ int column = 1;
+
+ public MatrixSymbol mulitply(MatrixSymbol other) {
+ MatrixSymbol matrixSymbol = new MatrixSymbol();
+ matrixSymbol.row = row;
+ matrixSymbol.column = other.column;
+ return matrixSymbol;
+ }
+ }
+
+ public static void main(String[] args) {
+
+ }
+
+ public static int multipiedNum(MatrixSymbol[] matrixArray) {
+ int[] multipliedNum = new int[matrixArray.length + 1];
+ MatrixSymbol[] multipliedMetrix = new MatrixSymbol[matrixArray.length + 1];
+ for (int i = 1; i < matrixArray.length; i++) {
+ int max = -1;
+ int lastMultiplied = 0;
+ MatrixSymbol lastMatrixSybmol = new MatrixSymbol();
+ for (int j = i; j > 0; j--) {
+ lastMultiplied += matrixArray[j].row;
+ }
+ }
+ return 0;
+ }
+}
diff --git a/src/main/java/org/wcong/test/algorithm/dp/PrintNearly.java b/src/main/java/org/wcong/test/algorithm/dp/PrintNearly.java
new file mode 100644
index 0000000..98cae57
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/dp/PrintNearly.java
@@ -0,0 +1,33 @@
+package org.wcong.test.algorithm.dp;
+
+/**
+ * Consider the problem of neatly printing a paragraph with a monospaced font (all
+ * characters having the same width) on a printer.
+ * The input text is a sequence of n words of lengths l1; l2; : : : ; ln, measured in characters.
+ * We want to print this paragraph neatly on a number of lines that hold a maximum of M characters each.
+ * Our criterion of “neatness” is as follows. If a given line contains words i through j ,
+ * where i <= j , and we leave exactly one space between words, the number of extra
+ * We wish to minimize the left space to right.
+ * Created by wcong on 2017/3/31.
+ */
+public class PrintNearly {
+
+ public static void main(String[] args) {
+
+ }
+
+ public static int paintNum(int[] array, int m) {
+ int[][] result = new int[array.length + 1][array.length + 1];
+ for (int i = 0; i < array.length; i++) {
+ for (int j = 0; j <= i; j++) {
+ if (array[i] + result[i][j] <= m) {
+ result[i + 1][j + 1] = result[i][j + 1] + array[i];
+ } else {
+ result[i + 1][j + 1] = result[i - 1][j] > result[i][j - 1] ? result[i - 1][j] : result[i][j - 1];
+ }
+ }
+ }
+ return result[array.length][array.length];
+ }
+
+}
diff --git a/src/main/java/org/wcong/test/algorithm/dp/RodCutting.java b/src/main/java/org/wcong/test/algorithm/dp/RodCutting.java
new file mode 100644
index 0000000..c14a7b8
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/dp/RodCutting.java
@@ -0,0 +1,29 @@
+package org.wcong.test.algorithm.dp;
+
+/**
+ * given a rod of length n inches and a table of n prices p[i] for i=1,2,3....
+ * determine the maximum revenue r(n) by cutting up rod and selling prices
+ * Created by wcong on 2017/3/30.
+ */
+public class RodCutting {
+
+ public static void main(String[] args) {
+
+ }
+
+ public static int rodCutting(int[] array, int n) {
+ int[] revenueArray = new int[n + 1];
+ for (int i = 1; i <= n; i++) {
+ int max = array[i];
+ for (int j = 1; j < i; j++) {
+ int revenue = revenueArray[j] + revenueArray[i - j];
+ if (revenue > max) {
+ max = revenue;
+ }
+ }
+ revenueArray[i] = max;
+ }
+ return revenueArray[n];
+ }
+
+}
diff --git a/src/main/java/org/wcong/test/algorithm/graph/Edge.java b/src/main/java/org/wcong/test/algorithm/graph/Edge.java
new file mode 100644
index 0000000..4e996bd
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/graph/Edge.java
@@ -0,0 +1,27 @@
+package org.wcong.test.algorithm.graph;
+
+/**
+ * Created by wcong on 2017/2/23.
+ */
+public class Edge {
+
+ private Vertices start;
+
+ private Vertices end;
+
+ public Vertices getStart() {
+ return start;
+ }
+
+ public void setStart(Vertices start) {
+ this.start = start;
+ }
+
+ public Vertices getEnd() {
+ return end;
+ }
+
+ public void setEnd(Vertices end) {
+ this.end = end;
+ }
+}
diff --git a/src/main/java/org/wcong/test/algorithm/graph/Graph.java b/src/main/java/org/wcong/test/algorithm/graph/Graph.java
new file mode 100644
index 0000000..896fbf6
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/graph/Graph.java
@@ -0,0 +1,40 @@
+package org.wcong.test.algorithm.graph;
+
+import java.util.List;
+
+/**
+ * Created by wcong on 2017/2/23.
+ */
+public class Graph {
+
+ private int vertices;
+
+ private int edge;
+
+ private List[] adjacencyList;
+
+
+ public int getVertices() {
+ return vertices;
+ }
+
+ public void setVertices(int vertices) {
+ this.vertices = vertices;
+ }
+
+ public int getEdge() {
+ return edge;
+ }
+
+ public void setEdge(int edge) {
+ this.edge = edge;
+ }
+
+ public List[] getAdjacencyList() {
+ return adjacencyList;
+ }
+
+ public void setAdjacencyList(List[] adjacencyList) {
+ this.adjacencyList = adjacencyList;
+ }
+}
diff --git a/src/main/java/org/wcong/test/algorithm/graph/TopologicalSort.java b/src/main/java/org/wcong/test/algorithm/graph/TopologicalSort.java
new file mode 100644
index 0000000..e4da4c1
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/graph/TopologicalSort.java
@@ -0,0 +1,10 @@
+package org.wcong.test.algorithm.graph;
+
+/**
+ * topological sort
+ *
+ * @author wcong
+ * @since 2017/4/9
+ */
+public class TopologicalSort {
+}
diff --git a/src/main/java/org/wcong/test/algorithm/graph/Vertices.java b/src/main/java/org/wcong/test/algorithm/graph/Vertices.java
new file mode 100644
index 0000000..6301b98
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/graph/Vertices.java
@@ -0,0 +1,18 @@
+package org.wcong.test.algorithm.graph;
+
+/**
+ * Created by wcong on 2017/2/23.
+ */
+public class Vertices {
+
+ private T t;
+
+
+ public T getT() {
+ return t;
+ }
+
+ public void setT(T t) {
+ this.t = t;
+ }
+}
diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/PowerOfNumber.java b/src/main/java/org/wcong/test/algorithm/jzoffer/PowerOfNumber.java
new file mode 100644
index 0000000..467bed9
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/jzoffer/PowerOfNumber.java
@@ -0,0 +1,66 @@
+package org.wcong.test.algorithm.jzoffer;
+
+import org.springframework.util.Assert;
+
+/**
+ * test for exception and number operation
+ * give a base number and a exponent return of power of them
+ * Created by wcong on 2017/3/24.
+ */
+public class PowerOfNumber {
+
+ public static void main(String[] args) {
+ Assert.isTrue(powerSlow(3, 9) == powerLogN(3, 9));
+ Assert.isTrue(powerSlow(-3, -9) == powerLogN(-3, -9));
+ Assert.isTrue(powerSlow(0, 0) == powerLogN(0, 0));
+ }
+
+ //
+ public static double powerSlow(double base, int exponent) {
+ if (base == 0 && exponent <= 0) {
+ throw new RuntimeException("no meaning");
+ }
+
+ if (exponent == 0)
+ return 1;
+ boolean positive = exponent >= 0;
+ exponent = positive ? exponent : -exponent;
+ double result = base;
+ for (int i = 1; i < exponent; i++) {
+ result *= base;
+ }
+ if (!positive) {
+ result = 1.0 / result;
+ }
+ return result;
+ }
+
+ public static double powerLogN(double base, int exponent) {
+ if (base == 0 && exponent <= 0) {
+ throw new RuntimeException("no meaning");
+ }
+ if (exponent == 0)
+ return 1;
+ boolean positive = exponent >= 0;
+ exponent = positive ? exponent : -exponent;
+ double result = power(base, exponent);
+ if (!positive) {
+ result = 1.0 / result;
+ }
+ return result;
+ }
+
+ private static double power(double base, int exponent) {
+ double result = 1.0;
+ if (exponent <= 0) {
+ return result;
+ }
+ result = power(base, exponent >> 1);
+ result *= result;
+ if ((exponent & 1) > 0) {
+ result *= base;
+ }
+ return result;
+ }
+
+}
diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/PrintNumberOfN.java b/src/main/java/org/wcong/test/algorithm/jzoffer/PrintNumberOfN.java
new file mode 100644
index 0000000..f9680a9
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/jzoffer/PrintNumberOfN.java
@@ -0,0 +1,43 @@
+package org.wcong.test.algorithm.jzoffer;
+
+/**
+ * test number limit boundary
+ * give a number n print all the numbers of decimal
+ *
+ * @author wcong
+ * @since 2017/3/26
+ */
+public class PrintNumberOfN {
+
+ public static void main(String[] args) {
+ printNumberOfN(3);
+ }
+
+ public static void printNumberOfN(int n) {
+ char[] number = new char[n];
+ printInteger(number, 0, n - 1);
+ }
+
+ private static void printInteger(char[] number, int index, int n) {
+ if (index > n) {
+ int startIndex = 0;
+ while (startIndex < n) {
+ if (number[startIndex] == 48) {
+ startIndex += 1;
+ } else {
+ break;
+ }
+ }
+ while (startIndex <= n) {
+ System.out.print(number[startIndex++]);
+ }
+ System.out.print("\n");
+ return;
+ }
+ for (int j = 48; j < 58; j++) {
+ number[index] = (char) j;
+ printInteger(number, index + 1, n);
+ }
+ }
+
+}
diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/array/CountInSortedArray.java b/src/main/java/org/wcong/test/algorithm/jzoffer/array/CountInSortedArray.java
new file mode 100644
index 0000000..47d854b
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/jzoffer/array/CountInSortedArray.java
@@ -0,0 +1,51 @@
+package org.wcong.test.algorithm.jzoffer.array;
+
+/**
+ * test for array and binary search
+ * give a sorted array count the target appear num
+ * Created by wcong on 2017/3/28.
+ */
+public class CountInSortedArray {
+
+ public static void main(String[] args) {
+
+ }
+
+ private static int countInSortedArray(int[] array, int target) {
+ int index = index(array, 0, array.length - 1, target);
+ if (index == 0) {
+ return 0;
+ }
+ int count = 1;
+ for (int i = index - 1; i > 0; i--) {
+ if (array[i] == target) {
+ count += 1;
+ } else {
+ break;
+ }
+ }
+ for (int i = index + 1; i < array.length; i++) {
+ if (array[i] == target) {
+ count += 1;
+ } else {
+ break;
+ }
+ }
+ return count;
+ }
+
+ public static int index(int[] array, int start, int end, int target) {
+ if (start < end) {
+ return -1;
+ }
+ int middle = start + (end - start) / 2;
+ if (array[middle] == target) {
+ return middle;
+ } else if (array[middle] > target) {
+ return index(array, start, middle - 1, target);
+ } else {
+ return index(array, middle + 1, end, target);
+ }
+ }
+
+}
diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/array/FindInTwoDimension.java b/src/main/java/org/wcong/test/algorithm/jzoffer/array/FindInTwoDimension.java
new file mode 100644
index 0000000..fca9bc8
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/jzoffer/array/FindInTwoDimension.java
@@ -0,0 +1,79 @@
+package org.wcong.test.algorithm.jzoffer.array;
+
+import org.springframework.util.Assert;
+
+/**
+ * test for array
+ * in a sorted tow dimension array,which is increasing from left to right,top to bottom.
+ * is there a target in that array.
+ * Created by wcong on 2017/3/23.
+ */
+public class FindInTwoDimension {
+
+ public static void main(String[] args) {
+ int[][] findMatrix = new int[][]{{1, 4, 7, 10, 13}, {2, 5, 8, 16, 17}, {3, 6, 9, 12, 15}};
+ Assert.isTrue(findInTwoDimensionLogN(findMatrix, 5));
+ Assert.isTrue(!findInTwoDimensionLogN(findMatrix, 11));
+ Assert.isTrue(!findInTwoDimensionLogN(null, 11));
+ }
+
+ public static boolean findInDimensionBigON(int[][] matrix, int target) {
+ if (matrix == null) {
+ return false;
+ }
+ for (int i = 0; i < matrix.length; i++) {
+ int start = 0;
+ int end = matrix[i].length;
+ while (start <= end) {
+ int middle = start + (end - start) / 2;
+ if (matrix[i][middle] == target) {
+ return true;
+ } else if (matrix[i][middle] < target) {
+ start = middle + 1;
+ } else {
+ end = middle - 1;
+ }
+ }
+ }
+ return false;
+ }
+
+ public static boolean findInTwoDimensionLogN(int[][] matrix, int target) {
+ if (matrix == null || matrix.length <= 0) {
+ return false;
+ }
+ return findInTwoDimensionSub(matrix, 0, matrix[0].length - 1, target);
+ }
+
+ public static boolean findInTwoDimensionSub(int[][] matrix, int row, int column, int target) {
+ if (row >= matrix.length) {
+ return false;
+ }
+ int startColumn = 0;
+ int endColumn = column;
+ while (startColumn <= endColumn) {
+ int middle = startColumn + (endColumn - startColumn) / 2;
+ if (matrix[row][middle] == target) {
+ return true;
+ } else if (matrix[row][middle] > target) {
+ endColumn = middle - 1;
+ } else {
+ startColumn = middle + 1;
+ }
+ }
+ int startRow = row;
+ int endRow = matrix.length - 1;
+ while (startRow <= endRow) {
+ int middle = startRow + (endRow - startRow) / 2;
+ if (matrix[middle][endColumn] == target) {
+ return true;
+ } else if (matrix[middle][endColumn] < target) {
+ startRow = middle + 1;
+ } else {
+ endRow = middle - 1;
+ }
+ }
+ return findInTwoDimensionSub(matrix, endRow + 1, endColumn - 1, target);
+ }
+
+}
diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/array/MaxSumSubArray.java b/src/main/java/org/wcong/test/algorithm/jzoffer/array/MaxSumSubArray.java
new file mode 100644
index 0000000..13f994e
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/jzoffer/array/MaxSumSubArray.java
@@ -0,0 +1,34 @@
+package org.wcong.test.algorithm.jzoffer.array;
+
+import org.springframework.util.Assert;
+
+/**
+ * test for array
+ * give a array find the max sum of sub array
+ * for example 1,-2,3,10,-4,7,2,-5 max 18
+ * Created by hzwangcong on 2017/3/28.
+ */
+public class MaxSumSubArray {
+
+
+ public static void main(String[] args) {
+ Assert.isTrue(maxSum(new int[]{1, -2, 3, 10, -4, 7, 2, -5}) == 18);
+ }
+
+ public static int maxSum(int[] array) {
+ int maxSum = array[0];
+ int currentSum = array[0];
+ for (int i = 1; i < array.length; i++) {
+ if (currentSum <= 0) {
+ currentSum = array[i];
+ }else{
+ currentSum+=array[i];
+ }
+ if (currentSum > maxSum) {
+ maxSum = currentSum;
+ }
+ }
+ return maxSum;
+ }
+
+}
diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/array/MinKNum.java b/src/main/java/org/wcong/test/algorithm/jzoffer/array/MinKNum.java
new file mode 100644
index 0000000..7fdd46c
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/jzoffer/array/MinKNum.java
@@ -0,0 +1,90 @@
+package org.wcong.test.algorithm.jzoffer.array;
+
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.PriorityQueue;
+
+/**
+ * test for array and partition and sorting
+ * Created by hzwangcong on 2017/3/27.
+ */
+public class MinKNum {
+
+ public static void main(String[] args) {
+ int[] array = new int[]{4, 5, 7, 1, 2, 4, 5, 6};
+ minKNumPartition(array, 2);
+ minKNumSort(array, 2);
+ }
+
+
+ public static int[] minKNumPartition(int[] array, int k) {
+ if (array == null || k <= 0) {
+ return null;
+ }
+ if (array.length <= k) {
+ return array;
+ }
+ int start = 0, end = array.length - 1;
+ while (end != k - 1) {
+ int middle = start + (end - start) / 2;
+ int middleValue = array[middle];
+ array[middle] = array[end];
+ array[end] = middleValue;
+ int i = start - 1;
+ for (int j = start; j < end; j++) {
+ if (array[j] <= middleValue) {
+ i += 1;
+ if (i != j) {
+ int temp = array[i];
+ array[i] = array[j];
+ array[j] = temp;
+ }
+ }
+ }
+ i += 1;
+ int temp = array[i];
+ array[i] = array[end];
+ array[end] = temp;
+ if (i == k - 1) {
+ end = i;
+ } else if (i > k - 1) {
+ end = k - 1;
+ } else {
+ start = i + 1;
+ }
+ }
+ return Arrays.copyOf(array, k);
+ }
+
+ public static int[] minKNumSort(int[] array, int k) {
+ if (array == null || k <= 0) {
+ return null;
+ }
+ if (array.length <= k) {
+ return array;
+ }
+ PriorityQueue minKQueue = new PriorityQueue<>(k, new Comparator() {
+ @Override
+ public int compare(Integer o1, Integer o2) {
+ return o2.compareTo(o1);
+ }
+ });
+ for (int i = 0; i < array.length; i++) {
+ if (minKQueue.size() < k) {
+ minKQueue.add(array[i]);
+ } else {
+ minKQueue.add(array[i]);
+ minKQueue.poll();
+ }
+ }
+ int[] result = new int[k];
+ int index = 0;
+ for (int num : minKQueue) {
+ result[index] = num;
+ index += 1;
+ }
+ return result;
+ }
+
+
+}
diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/array/MinNumInRotateArray.java b/src/main/java/org/wcong/test/algorithm/jzoffer/array/MinNumInRotateArray.java
new file mode 100644
index 0000000..2663ba4
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/jzoffer/array/MinNumInRotateArray.java
@@ -0,0 +1,61 @@
+package org.wcong.test.algorithm.jzoffer.array;
+
+import org.springframework.util.Assert;
+
+import java.util.Arrays;
+
+/**
+ * test for sort and search
+ * give a sorted array and rotate some num,find the min num in it
+ * Created by wcong on 2017/3/24.
+ */
+public class MinNumInRotateArray {
+
+ public static void main(String[] args) {
+ Assert.isTrue(Arrays.equals(rotateArray(new int[]{1, 2, 3, 4, 5, 6, 7}, 2), new int[]{6, 7, 1, 2, 3, 4, 5}));
+ Assert.isTrue(Arrays.equals(rotateArray(new int[]{1, 2, 3, 4, 5, 6, 7}, 5), new int[]{3, 4, 5, 6, 7, 1, 2}));
+ Assert.isTrue(Arrays.equals(rotateArray(new int[]{1, 2, 3, 4, 5, 6, 7, 8}, 4), new int[]{5, 6, 7, 8, 1, 2, 3, 4}));
+ Assert.isTrue(findMinNumForRotateArray(rotateArray(new int[]{1, 2, 3, 4, 5, 6, 7, 8}, 4))==1);
+ Assert.isTrue(findMinNumForRotateArray(rotateArray(new int[]{1, 2, 3, 4, 5, 6, 7}, 5))==1);
+ Assert.isTrue(findMinNumForRotateArray(rotateArray(new int[]{1, 2, 3, 4, 5, 6, 7}, 2))==1);
+ }
+
+ // example 12345678 34567812
+ private static int[] rotateArray(int[] array, int rotate) {
+ if (array == null || array.length <= 1 || rotate <= 0) {
+ return array;
+ }
+ int n = array.length;
+ int start = 0;
+ while (n > 0 && (rotate = rotate % n) > 0) {
+ for (int i = 0; i < rotate; i++) {
+ int index = start + i;
+ int swapIndex = n - rotate + i + start;
+ int temp = array[index];
+ array[index] = array[swapIndex];
+ array[swapIndex] = temp;
+ }
+ start += rotate;
+ n -= rotate;
+ }
+ return array;
+ }
+
+ private static int findMinNumForRotateArray(int[] array) {
+ if (array == null || array.length == 0) {
+ throw new RuntimeException("wrong array");
+ }
+ int first = array[0];
+ int left = 0, right = array.length - 1;
+ while (left <= right) {
+ int middle = left + (right - left) / 2;
+ if (array[middle] > first) {
+ left = middle + 1;
+ } else {
+ right = middle - 1;
+ }
+ }
+ return array[left];
+ }
+
+}
diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/array/MoreThanHalfInArray.java b/src/main/java/org/wcong/test/algorithm/jzoffer/array/MoreThanHalfInArray.java
new file mode 100644
index 0000000..27c4731
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/jzoffer/array/MoreThanHalfInArray.java
@@ -0,0 +1,33 @@
+package org.wcong.test.algorithm.jzoffer.array;
+
+import org.eclipse.core.runtime.Assert;
+
+/**
+ * test for array
+ * give a array and there is a num appear more than a half find it
+ * Created by hzwangcong on 2017/3/27.
+ */
+public class MoreThanHalfInArray {
+
+ public static void main(String[] args) {
+ Assert.isTrue(halfNum(new int[]{1, 2, 1, 1, 3, 1, 4}) == 1);
+ }
+
+ public static int halfNum(int[] array) {
+ int num = array[0];
+ int count = 1;
+ for (int i = 1; i < array.length; i++) {
+ if (array[i] == num) {
+ count += 1;
+ } else {
+ count -= 1;
+ }
+ if (count <= 0) {
+ num = array[i];
+ count = 1;
+ }
+ }
+ return num;
+ }
+
+}
diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/array/ReArrangeOddAndEven.java b/src/main/java/org/wcong/test/algorithm/jzoffer/array/ReArrangeOddAndEven.java
new file mode 100644
index 0000000..1400cdf
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/jzoffer/array/ReArrangeOddAndEven.java
@@ -0,0 +1,45 @@
+package org.wcong.test.algorithm.jzoffer.array;
+
+import org.springframework.util.Assert;
+
+import java.util.Arrays;
+
+/**
+ * test for array and odd and even and two pointers
+ * give an array of integer rearrange odd number to left and even number to left
+ *
+ * @author wcong
+ * @since 2017/3/26
+ */
+public class ReArrangeOddAndEven {
+
+ public static void main(String[] args) {
+ Assert.isTrue(
+ Arrays.equals(rearrange(new int[] { 1, 2, 3, 4, 5, 6, 7, 8 }), new int[] { 1, 7, 3, 5, 4, 6, 2, 8 }));
+ }
+
+ public static int[] rearrange(int[] array) {
+ if (array == null || array.length == 0) {
+ return array;
+ }
+ int leftEvenIndex = 0;
+ int rightOddIndex = array.length - 1;
+ while (leftEvenIndex < rightOddIndex) {
+ if ((array[leftEvenIndex] & 1) != 0) {
+ leftEvenIndex += 1;
+ continue;
+ }
+ if ((array[rightOddIndex] & 1) == 0) {
+ rightOddIndex -= 1;
+ continue;
+ }
+ int temp = array[leftEvenIndex];
+ array[leftEvenIndex] = array[rightOddIndex];
+ array[rightOddIndex] = temp;
+ leftEvenIndex += 1;
+ rightOddIndex -= 1;
+ }
+ return array;
+ }
+
+}
diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/array/ReplaceBlank.java b/src/main/java/org/wcong/test/algorithm/jzoffer/array/ReplaceBlank.java
new file mode 100644
index 0000000..6fa32b6
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/jzoffer/array/ReplaceBlank.java
@@ -0,0 +1,37 @@
+package org.wcong.test.algorithm.jzoffer.array;
+
+import org.springframework.util.Assert;
+
+/**
+ * test for string
+ * give a string replace all blank by %20
+ * Created by wcong on 2017/3/23.
+ */
+public class ReplaceBlank {
+
+ public static void main(String[] args) {
+ Assert.isTrue(replaceString("abs as das ").equals("abs%20as%20%20das%20"));
+ }
+
+ public static String replaceString(String oldString) {
+ int length = oldString.length();
+ for (int i = 0; i < oldString.length(); i++) {
+ if (oldString.charAt(i) == ' ') {
+ length += 2;
+ }
+ }
+ char[] newChar = new char[length];
+ int newCharIndex = 0;
+ for (int i = 0; i < oldString.length(); i++) {
+ if (oldString.charAt(i) == ' ') {
+ newChar[newCharIndex++] = '%';
+ newChar[newCharIndex++] = '2';
+ newChar[newCharIndex++] = '0';
+ } else {
+ newChar[newCharIndex++] = oldString.charAt(i);
+ }
+ }
+ return new String(newChar);
+ }
+
+}
diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/array/ReverseOrderPareInArray.java b/src/main/java/org/wcong/test/algorithm/jzoffer/array/ReverseOrderPareInArray.java
new file mode 100644
index 0000000..593355f
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/jzoffer/array/ReverseOrderPareInArray.java
@@ -0,0 +1,55 @@
+package org.wcong.test.algorithm.jzoffer.array;
+
+import org.springframework.util.Assert;
+
+/**
+ * test for array and recursive TODO
+ * Created by wcong on 2017/3/28.
+ */
+public class ReverseOrderPareInArray {
+
+ public static void main(String[] args) {
+ Assert.isTrue(reversPairsCount(new int[]{7, 5, 6, 4}) == 5);
+ }
+
+ public static int reversPairsCount(int[] array) {
+ if (array == null || array.length < 2) {
+ return 0;
+ }
+ int[] copy = new int[array.length];
+ for (int i = 0; i < array.length; i++) {
+ copy[i] = array[i];
+ }
+ return count(array, copy, 0, array.length - 1);
+ }
+
+ private static int count(int[] original, int[] copy, int start, int end) {
+ if (start == end) {
+ copy[start] = original[start];
+ return 0;
+ }
+ int length = (end - start) / 2;
+ int left = count(copy, original, start, start + length);
+ int right = count(copy, original, start + length + 1, end);
+ int merge = 0;
+ int leftEnd = start + length;
+ int rightEnd = end;
+ int current = end;
+ while (leftEnd >= start && rightEnd > (start + length)) {
+ if (original[leftEnd] > original[rightEnd]) {
+ merge += rightEnd - start - length;
+ copy[current--] = original[leftEnd--];
+ } else {
+ copy[current--] = original[rightEnd--];
+ }
+ }
+ while (leftEnd >= start) {
+ copy[current--] = original[leftEnd--];
+ }
+ while (rightEnd > start + length) {
+ copy[current--] = original[rightEnd--];
+ }
+ return left + right + merge;
+ }
+
+}
diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/array/SortedArraySumTarget.java b/src/main/java/org/wcong/test/algorithm/jzoffer/array/SortedArraySumTarget.java
new file mode 100644
index 0000000..56d7737
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/jzoffer/array/SortedArraySumTarget.java
@@ -0,0 +1,40 @@
+package org.wcong.test.algorithm.jzoffer.array;
+
+import org.springframework.util.Assert;
+
+import java.util.Arrays;
+
+/**
+ * test for array and tow pointer
+ * give a sorted array return two num sum to a target
+ * for example 1,2,4,7,11,15 target 12
+ * Created by wcong on 2017/3/28.
+ */
+public class SortedArraySumTarget {
+
+ public static void main(String[] args) {
+ Assert.isTrue(Arrays.equals(sumTarget(new int[]{1, 2, 4, 7, 11, 15}, 12), new int[]{0, 4}));
+ Assert.isTrue(Arrays.equals(sumTarget(new int[]{1, 2, 4, 7, 11, 15}, 11), new int[]{2, 3}));
+ }
+
+ public static int[] sumTarget(int[] array, int target) {
+ if (array == null || array.length < 2) {
+ return null;
+ }
+ int start = 0;
+ int end = array.length - 1;
+ int sum;
+ while (start < end) {
+ sum = array[start] + array[end];
+ if (sum == target) {
+ return new int[]{start, end};
+ } else if (sum > target) {
+ end -= 1;
+ } else {
+ start += 1;
+ }
+ }
+ return null;
+ }
+
+}
diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/array/SortedArraySumTargetSubSerial.java b/src/main/java/org/wcong/test/algorithm/jzoffer/array/SortedArraySumTargetSubSerial.java
new file mode 100644
index 0000000..c7cb336
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/jzoffer/array/SortedArraySumTargetSubSerial.java
@@ -0,0 +1,46 @@
+package org.wcong.test.algorithm.jzoffer.array;
+
+import java.util.Arrays;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * test for array and two pointer
+ * give a sorted array return all serial sub array sum to target
+ * for example a array 1,2,3,4,5,6,7,8 target 15 will give {1,2,3,4,5} {4,5,6} {7,8}
+ * Created by wcong on 2017/3/28.
+ */
+public class SortedArraySumTargetSubSerial {
+
+
+ public static void main(String[] args) {
+ subSerial(new int[]{1, 2, 3, 4, 5, 6, 7, 8}, 15);
+ }
+
+ public static List subSerial(int[] array, int target) {
+ if (array == null || array.length < 2) {
+ return null;
+ }
+ List resultList = new LinkedList<>();
+ int left = 0, right = 1;
+ int sum = array[left] + array[right];
+ while (right < array.length) {
+ if (sum > target) {
+ if (left == right) {
+ break;
+ }
+ sum -= array[left++];
+ } else if (sum < target) {
+ if (right == array.length - 1) {
+ break;
+ }
+ sum += array[++right];
+ }
+ if (sum == target) {
+ resultList.add(Arrays.copyOfRange(array, left, right + 1));
+ sum -= array[left++];
+ }
+ }
+ return resultList;
+ }
+}
diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/binary/Count1InInt.java b/src/main/java/org/wcong/test/algorithm/jzoffer/binary/Count1InInt.java
new file mode 100644
index 0000000..bcf53b2
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/jzoffer/binary/Count1InInt.java
@@ -0,0 +1,43 @@
+package org.wcong.test.algorithm.jzoffer.binary;
+
+import org.springframework.util.Assert;
+
+/**
+ * test for binary operate and or xor and smart move to recursive
+ * >> remain the sign bit,>>> ignore the sign bit
+ *
+ * @author wcong
+ * @since 2017/3/26
+ */
+public class Count1InInt {
+
+ public static void main(String[] args) {
+ Assert.isTrue(count1Slow(0xFFFF) == count1Smart(0xFFFF));
+ Assert.isTrue(count1Slow(0x4444) == count1Smart(0x4444));
+ Assert.isTrue(count1Slow(0x3214) == count1Smart(0x3214));
+ Assert.isTrue(count1Slow(0x10) == count1Smart(0x10));
+ Assert.isTrue(count1Slow(0x1111) == count1Smart(0x1111));
+ }
+
+ public static int count1Slow(int num) {
+ int count = 0;
+ while (num != 0) {
+ if ((num & 1) != 0) {
+ count += 1;
+ }
+ num = num >> 1;
+ }
+ return count;
+ }
+
+ public static int count1Smart(int num) {
+ num = num < 0 ? -num : num;
+ int count = 0;
+ while (num > 0) {
+ count += 1;
+ num = num & (num - 1);
+ }
+ return count;
+ }
+
+}
diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/binary/TwoDifferentNumInArray.java b/src/main/java/org/wcong/test/algorithm/jzoffer/binary/TwoDifferentNumInArray.java
new file mode 100644
index 0000000..9727f89
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/jzoffer/binary/TwoDifferentNumInArray.java
@@ -0,0 +1,43 @@
+package org.wcong.test.algorithm.jzoffer.binary;
+
+/**
+ * test for bit operation and array
+ * give a array two of the numbers appears only once others all appears twice,find the tow number
+ * Created by wcong on 2017/3/28.
+ */
+public class TwoDifferentNumInArray {
+
+ public static void main(String[] args) {
+ twoNumbers(new int[]{1, 2, 3, 4, 5, 6, 4, 3, 2, 5});
+ }
+
+
+ public static int[] twoNumbers(int[] array) {
+ if (array == null || array.length < 2) {
+ return null;
+ }
+ int result = 0;
+ for (int num : array) {
+ result ^= num;
+ }
+ int bitIndex = 0;
+ while (result != 0) {
+ if ((result & 1) != 0) {
+ break;
+ }
+ result = result >> 1;
+ bitIndex += 1;
+ }
+ int num1 = 0;
+ int num2 = 0;
+ for (int num : array) {
+ if (((num >> bitIndex) & 1) == 0) {
+ num1 ^= num;
+ } else {
+ num2 ^= num;
+ }
+ }
+ return new int[]{num1, num2};
+ }
+
+}
diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/dp/Fibonacci.java b/src/main/java/org/wcong/test/algorithm/jzoffer/dp/Fibonacci.java
new file mode 100644
index 0000000..78f0af3
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/jzoffer/dp/Fibonacci.java
@@ -0,0 +1,30 @@
+package org.wcong.test.algorithm.jzoffer.dp;
+
+import org.eclipse.core.runtime.Assert;
+
+/**
+ * test for recursive and numbers
+ * Created by wcong on 2017/3/24.
+ */
+public class Fibonacci {
+
+ public static void main(String[] args) {
+ Assert.isTrue(fibonacci(2) == 2);
+ Assert.isTrue(fibonacci(4) == 5);
+ Assert.isTrue(fibonacci(6) == 13);
+ }
+
+ static int fibonacci(int n) {
+ if (n < 2) {
+ return 1;
+ }
+ int last = 1;
+ int lastOfLast = 1;
+ for (int i = 2; i < n; i++) {
+ int now = last + lastOfLast;
+ lastOfLast = last;
+ last = now;
+ }
+ return last + lastOfLast;
+ }
+}
diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/dp/NumberOf1BeforeN.java b/src/main/java/org/wcong/test/algorithm/jzoffer/dp/NumberOf1BeforeN.java
new file mode 100644
index 0000000..8374983
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/jzoffer/dp/NumberOf1BeforeN.java
@@ -0,0 +1,63 @@
+package org.wcong.test.algorithm.jzoffer.dp;
+
+import org.eclipse.core.runtime.Assert;
+
+/**
+ * test for number and divide and conquer
+ * give a number n count all the 1 appear from 1 to n;
+ * for example n=11 count = 3
+ * Created by wcong on 2017/3/28.
+ */
+public class NumberOf1BeforeN {
+
+ public static void main(String[] args) {
+ Assert.isTrue(count1(11) == 4);
+ Assert.isTrue(count1(21) == 13);
+ }
+
+ // for example 11 have 4 : 1 10 11 , 21 have 13
+ public static int count1(int n) {
+ if (n < 1) {
+ return 0;
+ }
+ if (n < 10) {
+ return 1;
+ }
+ int current = n;
+ int exponent = 0;
+ int maxTen = 1;
+ while (current >= 10) {
+ maxTen *= 10;
+ exponent += 1;
+ current /= 10;
+ }
+ return count1(n, maxTen, exponent);
+ }
+
+ private static int count1(int n, int maxTen, int exponent) {
+ int count = 0;
+ if (n / maxTen == 1) {
+ count += n - maxTen + 1;
+ } else {
+ count += maxTen;
+ }
+ int lowExponent = countExponent(exponent);
+ while (n > maxTen) {
+ count += lowExponent;
+ n -= maxTen;
+ }
+ count += count1(n);
+ return count;
+ }
+
+ private static int countExponent(int exponent) {
+ if (exponent == 0) {
+ return 0;
+ }
+ if (exponent == 1) {
+ return 1;
+ }
+ return 10 * countExponent(exponent - 1) + (int) Math.pow(10, exponent - 1);
+ }
+
+}
diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/dp/UglyNumber.java b/src/main/java/org/wcong/test/algorithm/jzoffer/dp/UglyNumber.java
new file mode 100644
index 0000000..2990190
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/jzoffer/dp/UglyNumber.java
@@ -0,0 +1,39 @@
+package org.wcong.test.algorithm.jzoffer.dp;
+
+import org.springframework.util.Assert;
+
+/**
+ * test for number
+ * ugly number only contains 2,3,4 for multiply count target number of ugly number
+ * Created by wcong on 2017/3/29.
+ */
+public class UglyNumber {
+
+ public static void main(String[] args) {
+ Assert.isTrue(nThUglyNumber(9) == 12);
+ Assert.isTrue(nThUglyNumber(10) == 15);
+ }
+
+ public static int nThUglyNumber(int n) {
+ int[] ugly = new int[n + 1];
+ ugly[0] = 1;
+ int index2 = 0;
+ int index3 = 0;
+ int index5 = 0;
+ for (int i = 1; i <= n; i++) {
+ int min = Math.min(Math.min(ugly[index2] * 2, ugly[index3] * 3), ugly[index5] * 5);
+ ugly[i] = min;
+ while (ugly[index2] * 2 <= min) {
+ index2 += 1;
+ }
+ while (ugly[index3] * 3 <= min) {
+ index3 += 1;
+ }
+ while (ugly[index5] * 5 <= min) {
+ index5 += 1;
+ }
+ }
+ return ugly[n];
+ }
+
+}
diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/linked_list/CommonNodeInTwoLinkedList.java b/src/main/java/org/wcong/test/algorithm/jzoffer/linked_list/CommonNodeInTwoLinkedList.java
new file mode 100644
index 0000000..fd819a0
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/jzoffer/linked_list/CommonNodeInTwoLinkedList.java
@@ -0,0 +1,55 @@
+package org.wcong.test.algorithm.jzoffer.linked_list;
+
+import org.springframework.util.Assert;
+import org.wcong.test.algorithm.jzoffer.util.BuildLinkedList;
+import org.wcong.test.algorithm.jzoffer.util.LinkedListNode;
+
+/**
+ * test for linked list
+ * give to linked list find the first common node
+ * Created by wcong on 2017/3/28.
+ */
+public class CommonNodeInTwoLinkedList {
+
+ public static void main(String[] args) {
+ Assert.isTrue(commmoNode(BuildLinkedList.makeOne(new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9}).root, BuildLinkedList.makeOne(new int[]{11, 12, 12, 14, 5, 6, 7, 8, 9}).root) == 5);
+ }
+
+ public static int commmoNode(LinkedListNode list1, LinkedListNode list2) {
+ if (list1 == null || list2 == null) {
+ throw new RuntimeException("wrong param");
+ }
+ int list1Length = 1, list2Length = 1;
+ LinkedListNode node = list1;
+ while (node.next != null) {
+ list1Length += 1;
+ node = node.next;
+ }
+ node = list2;
+ while (node.next != null) {
+ list2Length += 1;
+ node = node.next;
+ }
+ LinkedListNode startNode1 = list1;
+ LinkedListNode startNode2 = list2;
+ if (list1Length > list2Length) {
+ int length = list1Length - list2Length;
+ for (int i = 0; i < length; i++) {
+ startNode1 = startNode1.next;
+ }
+ } else if (list1Length < list2Length) {
+ int length = list2Length - list1Length;
+ for (int i = 0; i < length; i++) {
+ startNode2 = startNode2.next;
+ }
+ }
+ while (true) {
+ if (startNode1.value == startNode2.value) {
+ return startNode1.value;
+ }
+ startNode1 = startNode1.next;
+ startNode2 = startNode2.next;
+ }
+ }
+
+}
diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/linked_list/ComplexListNodeCopy.java b/src/main/java/org/wcong/test/algorithm/jzoffer/linked_list/ComplexListNodeCopy.java
new file mode 100644
index 0000000..c0cd72e
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/jzoffer/linked_list/ComplexListNodeCopy.java
@@ -0,0 +1,47 @@
+package org.wcong.test.algorithm.jzoffer.linked_list;
+
+import org.wcong.test.algorithm.jzoffer.util.ComplexListNode;
+
+/**
+ * test for linked list
+ * give a complex linked list copy it
+ *
+ * @author wcong
+ * @since 2017/3/26
+ */
+public class ComplexListNodeCopy {
+
+ public static ComplexListNode copyComplexList(ComplexListNode head) {
+ if (head == null) {
+ return null;
+ }
+ ComplexListNode node = head;
+ while (node != null) {
+ ComplexListNode copy = new ComplexListNode();
+ copy.value = node.value;
+ copy.next = node.next;
+ node.next = copy;
+ node = copy.next;
+ }
+ node = head;
+ while (node != null) {
+ ComplexListNode copy = node.next;
+ if (node.other != null) {
+ copy.other = node.other.next;
+ }
+ node = copy.next;
+ }
+ node = head;
+ ComplexListNode root = head.next;
+ while (node != null) {
+ ComplexListNode copy = node.next;
+ node.next = copy.next;
+ node = copy.next;
+ if( copy.next != null ) {
+ copy.next = copy.next.next;
+ }
+ }
+ return root;
+ }
+
+}
diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/linked_list/DeleteNodeInO1.java b/src/main/java/org/wcong/test/algorithm/jzoffer/linked_list/DeleteNodeInO1.java
new file mode 100644
index 0000000..699a10e
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/jzoffer/linked_list/DeleteNodeInO1.java
@@ -0,0 +1,42 @@
+package org.wcong.test.algorithm.jzoffer.linked_list;
+
+import org.springframework.util.Assert;
+
+/**
+ * test for linked list basic operate,search,add,delete
+ * give a linked list root and delete node,delete this node in O(1) time
+ *
+ * @author wcong
+ * @since 2017/3/26
+ */
+public class DeleteNodeInO1 {
+
+ public static void main(String[] args) {
+ }
+
+ public static class LinkedNode {
+ int value;
+
+ LinkedNode next;
+ }
+
+ public static LinkedNode deleteInO1(LinkedNode root, LinkedNode delete) {
+ if (root == null || delete == null) {
+ return null;
+ }
+ if (delete.next != null) {
+ delete.value = delete.next.value;
+ delete.next = delete.next.next;
+ } else if (root == delete) {
+ return null;
+ } else {
+ LinkedNode parent = root;
+ while (parent.next != delete) {
+ parent = parent.next;
+ }
+ parent.next = null;
+ }
+ return root;
+ }
+
+}
diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/linked_list/LastKNodeInLinkedList.java b/src/main/java/org/wcong/test/algorithm/jzoffer/linked_list/LastKNodeInLinkedList.java
new file mode 100644
index 0000000..c9cbb69
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/jzoffer/linked_list/LastKNodeInLinkedList.java
@@ -0,0 +1,39 @@
+package org.wcong.test.algorithm.jzoffer.linked_list;
+
+import org.springframework.util.Assert;
+import org.wcong.test.algorithm.jzoffer.util.BuildLinkedList;
+import org.wcong.test.algorithm.jzoffer.util.LinkedList;
+import org.wcong.test.algorithm.jzoffer.util.LinkedListNode;
+
+/**
+ * test for linked list and exceptions and continue thinking and two pointers
+ *
+ * @author wcong
+ * @since 2017/3/26
+ */
+public class LastKNodeInLinkedList {
+
+ public static void main(String[] args) {
+ LinkedList one = BuildLinkedList.makeOne(new int[] { 1, 2, 3, 4, 5 });
+ Assert.isTrue(lastKNode(one, 6) == null);
+ Assert.isTrue(lastKNode(one, 3).value == 3);
+ }
+
+ public static LinkedListNode lastKNode(LinkedList linkedList, int k) {
+ if (linkedList == null || linkedList.root == null || k < 1) {
+ return null;
+ }
+ LinkedListNode lastKNode = linkedList.root;
+ int count = 1;
+ LinkedListNode node = linkedList.root;
+ while (node.next != null) {
+ count += 1;
+ node = node.next;
+ if (count > k) {
+ lastKNode = lastKNode.next;
+ }
+ }
+ return count < k ? null : lastKNode;
+ }
+
+}
diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/linked_list/MergeTwoSortedLinkedList.java b/src/main/java/org/wcong/test/algorithm/jzoffer/linked_list/MergeTwoSortedLinkedList.java
new file mode 100644
index 0000000..993407b
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/jzoffer/linked_list/MergeTwoSortedLinkedList.java
@@ -0,0 +1,53 @@
+package org.wcong.test.algorithm.jzoffer.linked_list;
+
+import org.springframework.util.Assert;
+import org.wcong.test.algorithm.jzoffer.util.BuildLinkedList;
+import org.wcong.test.algorithm.jzoffer.util.LinkedList;
+import org.wcong.test.algorithm.jzoffer.util.LinkedListNode;
+
+/**
+ * test linked list and merge
+ *
+ * @author wcong
+ * @since 2017/3/26
+ */
+public class MergeTwoSortedLinkedList {
+
+ public static void main(String[] args) {
+ LinkedList list1 = BuildLinkedList.makeOne(new int[] { 1, 3, 4, 5, 6 });
+ LinkedList list2 = BuildLinkedList.makeOne(new int[] { 2, 4, 7, 8, 9 });
+ LinkedList merge = BuildLinkedList.makeOne(new int[] { 1, 2, 3, 4, 4, 5, 6, 7, 8, 9 });
+ Assert.isTrue(mergeSortedList(list1, list2).equal(merge));
+ }
+
+ public static LinkedList mergeSortedList(LinkedList list1, LinkedList list2) {
+ if (list1 == null || list1.root == null) {
+ return list2;
+ }
+ if (list2 == null || list2.root == null) {
+ return list1;
+ }
+ LinkedListNode node1 = list1.root;
+ LinkedListNode node2 = list2.root;
+ LinkedList root = node1.value > node2.value ? list2 : list1;
+ while (node1 != null && node2 != null) {
+ if (node1.value < node2.value) {
+ while (node1.next != null && node1.next.value < node2.value) {
+ node1 = node1.next;
+ }
+ LinkedListNode temp = node1.next;
+ node1.next = node2;
+ node1 = temp;
+ } else if (node1.value >= node2.value) {
+ while (node2.next != null && node2.next.value <= node1.value) {
+ node2 = node2.next;
+ }
+ LinkedListNode temp = node2.next;
+ node2.next = node1;
+ node2 = temp;
+ }
+ }
+ return root;
+ }
+
+}
diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/linked_list/PrintLinkedListFromBottom.java b/src/main/java/org/wcong/test/algorithm/jzoffer/linked_list/PrintLinkedListFromBottom.java
new file mode 100644
index 0000000..ef811f9
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/jzoffer/linked_list/PrintLinkedListFromBottom.java
@@ -0,0 +1,20 @@
+package org.wcong.test.algorithm.jzoffer.linked_list;
+
+import java.util.List;
+
+/**
+ * test for linked list
+ * give a linked list pring it from bottom
+ * Created by wcong on 2017/3/23.
+ */
+public class PrintLinkedListFromBottom {
+
+ public static void main(String[] args) {
+
+ }
+
+ public static void printRecursive(List linkedList) {
+
+ }
+
+}
diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/linked_list/ReversLinkedList.java b/src/main/java/org/wcong/test/algorithm/jzoffer/linked_list/ReversLinkedList.java
new file mode 100644
index 0000000..bcb9eab
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/jzoffer/linked_list/ReversLinkedList.java
@@ -0,0 +1,40 @@
+package org.wcong.test.algorithm.jzoffer.linked_list;
+
+import org.springframework.util.Assert;
+import org.wcong.test.algorithm.jzoffer.util.BuildLinkedList;
+import org.wcong.test.algorithm.jzoffer.util.LinkedList;
+import org.wcong.test.algorithm.jzoffer.util.LinkedListNode;
+
+/**
+ * test for linked list
+ *
+ * @author wcong
+ * @since 2017/3/26
+ */
+public class ReversLinkedList {
+
+ public static void main(String[] args) {
+ LinkedList list = BuildLinkedList.makeOne(new int[] { 1, 2, 3, 4, 5, 6, 7 });
+ LinkedList reverseList = BuildLinkedList.makeOne(new int[] { 7, 6, 5, 4, 3, 2, 1 });
+ Assert.isTrue(reverse(list).equal(reverseList));
+ }
+
+ public static LinkedList reverse(LinkedList linkedList) {
+ if (linkedList == null || linkedList.root == null) {
+ return linkedList;
+ }
+ LinkedListNode before = null;
+ LinkedListNode node = linkedList.root;
+ LinkedListNode next = node.next;
+ node.next = null;
+ while (next != null) {
+ before = node;
+ node = next;
+ next = next.next;
+ node.next = before;
+ }
+ linkedList.root = node;
+ return linkedList;
+ }
+
+}
diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/stack/O1MinStack.java b/src/main/java/org/wcong/test/algorithm/jzoffer/stack/O1MinStack.java
new file mode 100644
index 0000000..8b06936
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/jzoffer/stack/O1MinStack.java
@@ -0,0 +1,40 @@
+package org.wcong.test.algorithm.jzoffer.stack;
+
+import java.util.Stack;
+
+/**
+ * test for stack and its operation
+ * implement a push pop and min all O(1) time use
+ *
+ * @author wcong
+ * @since 2017/3/26
+ */
+public class O1MinStack {
+
+ public static class MinO1Stack {
+
+ private Stack normal;
+
+ private Stack min;
+
+ public void push(int num) {
+ normal.push(num);
+ if (min.isEmpty() || min.lastElement() > num) {
+ min.push(num);
+ } else {
+ min.push(min.lastElement());
+ }
+ }
+
+ public int pop() {
+ min.pop();
+ return normal.pop();
+ }
+
+ public int min() {
+ return min.lastElement();
+ }
+
+ }
+
+}
diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/stack/StackPushPopRule.java b/src/main/java/org/wcong/test/algorithm/jzoffer/stack/StackPushPopRule.java
new file mode 100644
index 0000000..9ed9d5f
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/jzoffer/stack/StackPushPopRule.java
@@ -0,0 +1,49 @@
+package org.wcong.test.algorithm.jzoffer.stack;
+
+import org.springframework.util.Assert;
+
+/**
+ * test for stack operation
+ * give two array of integer,first is the order of push,judge second is the one of the order of pop
+ * for example push array 1,2,3,4,5 and pop order 4,5,3,2,1 is correct but 4,3,5,1,2 is not
+ *
+ * @author wcong
+ * @since 2017/3/26
+ */
+public class StackPushPopRule {
+
+ public static void main(String[] args) {
+ Assert.isTrue(isPopToPush(new int[]{1, 2, 3, 4, 5}, new int[]{4, 5, 3, 2, 1}));
+ Assert.isTrue(!isPopToPush(new int[]{1, 2, 3, 4, 5}, new int[]{4, 3, 5, 1, 2}));
+ }
+
+ public static boolean isPopToPush(int[] pushArray, int[] popArray) {
+ if (pushArray == null || popArray == null) {
+ return false;
+ }
+ int index = -1;
+ for (int push : pushArray) {
+ index += 1;
+ if (push == popArray[0]) {
+ break;
+ }
+ }
+ if (index < 0) {
+ return false;
+ }
+ int left = index - 1, right = index + 1;
+ for (int i = 1; i < popArray.length; i++) {
+ if (left >= 0 && pushArray[left] == popArray[i]) {
+ left -= 1;
+ continue;
+ }
+ if (right < pushArray.length && pushArray[right] == popArray[i]) {
+ right += 1;
+ continue;
+ }
+ return false;
+ }
+ return true;
+ }
+
+}
diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/stack/TwoStackForQueue.java b/src/main/java/org/wcong/test/algorithm/jzoffer/stack/TwoStackForQueue.java
new file mode 100644
index 0000000..2d66d92
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/jzoffer/stack/TwoStackForQueue.java
@@ -0,0 +1,48 @@
+package org.wcong.test.algorithm.jzoffer.stack;
+
+import org.springframework.util.Assert;
+
+import java.util.Stack;
+
+/**
+ * test for stack and queue
+ * implement a queue bu two stack
+ * Created by wcong on 2017/3/24.
+ */
+public class TwoStackForQueue {
+
+
+ public static void main(String[] args) {
+ StackQueue stackQueue = new StackQueue();
+ stackQueue.push(1);
+ stackQueue.push(2);
+ stackQueue.push(3);
+ stackQueue.push(4);
+ Assert.isTrue(stackQueue.pop() == 1);
+ Assert.isTrue(stackQueue.pop() == 2);
+ Assert.isTrue(stackQueue.pop() == 3);
+ Assert.isTrue(stackQueue.pop() == 4);
+ }
+
+
+ public static class StackQueue {
+
+ private Stack in = new Stack<>();
+
+ private Stack out = new Stack<>();
+
+ public void push(int num) {
+ in.push(num);
+ }
+
+ public int pop() {
+ if (out.isEmpty()) {
+ while (!in.isEmpty()) {
+ out.push(in.pop());
+ }
+ }
+ return out.pop();
+ }
+ }
+
+}
diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/tree/BinaryTreePostOrderWalkRule.java b/src/main/java/org/wcong/test/algorithm/jzoffer/tree/BinaryTreePostOrderWalkRule.java
new file mode 100644
index 0000000..67bd5cf
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/jzoffer/tree/BinaryTreePostOrderWalkRule.java
@@ -0,0 +1,46 @@
+package org.wcong.test.algorithm.jzoffer.tree;
+
+import org.springframework.util.Assert;
+
+/**
+ * test for binary search tree post-order walk analysis
+ * give a array of integer judge is binary search tree post-order walk
+ * for example 5,7,6,9,11,10,8 is true,7,4,6,5 is not
+ *
+ * @author wcong
+ * @since 2017/3/26
+ */
+public class BinaryTreePostOrderWalkRule {
+
+ public static void main(String[] args) {
+ Assert.isTrue(isBinarySearchTree(new int[]{5, 7, 6, 9, 11, 10, 8}));
+ Assert.isTrue(!isBinarySearchTree(new int[]{7, 4, 6, 5}));
+ }
+
+ public static boolean isBinarySearchTree(int[] array) {
+ if (array == null || array.length == 0) {
+ return false;
+ }
+ return isBinarySearchTree(array, 0, array.length - 1);
+ }
+
+ private static boolean isBinarySearchTree(int[] array, int start, int end) {
+ if (start > end || start < 0 || end > array.length) {
+ return true;
+ }
+ int middle = array[end];
+ int leftEnd = start;
+ for (; leftEnd < end; leftEnd++) {
+ if (array[leftEnd] >= middle) {
+ break;
+ }
+ }
+ leftEnd -= 1;
+ for (int i = leftEnd + 1; i < end; i++) {
+ if (array[i] < middle) {
+ return false;
+ }
+ }
+ return isBinarySearchTree(array, start, leftEnd) && isBinarySearchTree(array, leftEnd + 1, end - 1);
+ }
+}
diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/tree/ChangeBinaryTreeToDQueue.java b/src/main/java/org/wcong/test/algorithm/jzoffer/tree/ChangeBinaryTreeToDQueue.java
new file mode 100644
index 0000000..588555b
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/jzoffer/tree/ChangeBinaryTreeToDQueue.java
@@ -0,0 +1,44 @@
+package org.wcong.test.algorithm.jzoffer.tree;
+
+import org.wcong.test.algorithm.jzoffer.util.BuildTree;
+import org.wcong.test.algorithm.jzoffer.util.Tree;
+import org.wcong.test.algorithm.jzoffer.util.TreeNode;
+
+/**
+ * test for tree and dqueue TODO
+ * give a binary tree change it to dqueue
+ *
+ * @author wcong
+ * @since 2017/3/26
+ */
+public class ChangeBinaryTreeToDQueue {
+
+
+ public static void main(String[] args) {
+ changeToDQueue(BuildTree.buildOne(new int[]{4, 2, 6, 1, 3, 5, 7}));
+ }
+
+ public static TreeNode changeToDQueue(Tree tree) {
+ TreeNode treeNode = changeToDQueue(tree.root, null);
+ while (treeNode.left != null) {
+ treeNode = treeNode.left;
+ }
+ return treeNode;
+ }
+
+ private static TreeNode changeToDQueue(TreeNode treeNode, TreeNode lastInQueue) {
+ if (treeNode.left != null) {
+ lastInQueue = changeToDQueue(treeNode.left, lastInQueue);
+ }
+ if (lastInQueue != null) {
+ lastInQueue.right = treeNode;
+ treeNode.left = lastInQueue;
+ }
+ lastInQueue = treeNode;
+ if (treeNode.right != null) {
+ lastInQueue = changeToDQueue(treeNode.right, lastInQueue);
+ }
+ return lastInQueue;
+ }
+
+}
diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/tree/ConstructBinaryTree.java b/src/main/java/org/wcong/test/algorithm/jzoffer/tree/ConstructBinaryTree.java
new file mode 100644
index 0000000..cb8d69e
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/jzoffer/tree/ConstructBinaryTree.java
@@ -0,0 +1,100 @@
+package org.wcong.test.algorithm.jzoffer.tree;
+
+import org.springframework.util.Assert;
+
+import java.util.Stack;
+
+/**
+ * test for tree
+ * give a binary tree there inorder preorder postorder tree walk,
+ * build a binary tree by preorder 12473568 and inorder 47215386 out put
+ * Created by wcong on 2017/3/23.
+ */
+public class ConstructBinaryTree {
+
+
+ public static void main(String[] args) {
+ Assert.isTrue(constructBinaryTree("12473568", "47215386").preOrderString().equals("12473568"));
+ }
+
+ static class BinaryTreeNode {
+ char value;
+ BinaryTreeNode left;
+ BinaryTreeNode right;
+ }
+
+ static class BinaryTree {
+ BinaryTreeNode root;
+
+ @Override
+ public boolean equals(Object o) {
+ if (o == null) {
+ return false;
+ }
+ if (!(o instanceof BinaryTree)) {
+ return false;
+ }
+ return isEqual(root, ((BinaryTree) o).root);
+ }
+
+ private boolean isEqual(BinaryTreeNode node1, BinaryTreeNode node2) {
+ if (node1 == null && node2 == null) {
+ return true;
+ }
+ if (node1 != null && node2 != null) {
+ return node1.value == node2.value && isEqual(node1.left, node2.left) && isEqual(node1.right, node2.right);
+ }
+ return false;
+ }
+
+ public String preOrderString() {
+ StringBuilder sb = new StringBuilder(12);
+ Stack tempNodeStack = new Stack<>();
+ tempNodeStack.add(root);
+ while (!tempNodeStack.isEmpty()) {
+ BinaryTreeNode node = tempNodeStack.pop();
+ sb.append(node.value);
+ if (node.right != null) {
+ tempNodeStack.push(node.right);
+ }
+ if (node.left != null) {
+ tempNodeStack.push(node.left);
+ }
+ }
+ return sb.toString();
+ }
+ }
+
+ //by preorder 12473568 and inorder 47215386
+ static BinaryTree constructBinaryTree(String preOrder, String inOrder) {
+ if (preOrder == null || inOrder == null || preOrder.length() == 0 || inOrder.length() == 0 || preOrder.length() != inOrder.length()) {
+ return null;
+ }
+ char[] preOrderArray = preOrder.toCharArray();
+ char[] inOrderArray = inOrder.toCharArray();
+ BinaryTree binaryTree = new BinaryTree();
+ binaryTree.root = buildTree(preOrderArray, 0, preOrderArray.length - 1, inOrderArray, 0, inOrderArray.length - 1);
+ return binaryTree;
+ }
+
+ private static BinaryTreeNode buildTree(char[] preOrderArray, int preOrderArrayLeft, int preOrderArrayRight,
+ char[] inOrderArray, int inOrderArrayLeft, int inOrderArrayRight) {
+ if (preOrderArrayLeft > preOrderArrayRight) {
+ return null;
+ }
+ char inNode = preOrderArray[preOrderArrayLeft];
+ BinaryTreeNode node = new BinaryTreeNode();
+ node.value = inNode;
+ int leftIndex = inOrderArrayLeft;
+ while (leftIndex <= inOrderArrayRight) {
+ if (inOrderArray[leftIndex] == inNode) {
+ break;
+ }
+ leftIndex += 1;
+ }
+ node.left = buildTree(preOrderArray, preOrderArrayLeft + 1, preOrderArrayLeft+leftIndex-inOrderArrayLeft, inOrderArray, inOrderArrayLeft, leftIndex - 1);
+ node.right = buildTree(preOrderArray, preOrderArrayLeft+leftIndex-inOrderArrayLeft + 1, preOrderArrayRight, inOrderArray, leftIndex + 1, inOrderArrayRight);
+ return node;
+ }
+
+}
diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/tree/IsSubTree.java b/src/main/java/org/wcong/test/algorithm/jzoffer/tree/IsSubTree.java
new file mode 100644
index 0000000..85c0b9d
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/jzoffer/tree/IsSubTree.java
@@ -0,0 +1,54 @@
+package org.wcong.test.algorithm.jzoffer.tree;
+
+import org.wcong.test.algorithm.jzoffer.util.Tree;
+import org.wcong.test.algorithm.jzoffer.util.TreeNode;
+
+/**
+ * test for tree
+ *
+ * give tow tree,judge is one tree is other sub tree
+ *
+ * @author wcong
+ * @since 2017/3/26
+ */
+public class IsSubTree {
+
+ public static void main(String[] args) {
+
+ }
+
+ public static boolean isSubTree(Tree tree, Tree subTree) {
+ if (tree == null || tree.root == null || subTree == null || subTree.root == null) {
+ return false;
+ }
+ TreeNode subNode = subTree.root;
+ return isSubTree(tree.root, subNode);
+ }
+
+ public static boolean isSubTree(TreeNode node, TreeNode example) {
+ if (example == null || node == null) {
+ return false;
+ }
+ if (node.value == example.value) {
+ if (isContainTree(node, example)) {
+ return true;
+ }
+ }
+ boolean isSub = isSubTree(node.left, example);
+ return isSub || isSubTree(node.right, example);
+ }
+
+ private static boolean isContainTree(TreeNode node, TreeNode example) {
+ if (example == null) {
+ return true;
+ }
+ if (node == null) {
+ return false;
+ }
+ if (node.value == example.value && isContainTree(node.left, example.left) && isContainTree(node.right, example.right)) {
+ return true;
+ }
+ return false;
+ }
+
+}
diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/tree/MirrorOfBinaryTree.java b/src/main/java/org/wcong/test/algorithm/jzoffer/tree/MirrorOfBinaryTree.java
new file mode 100644
index 0000000..ca3d66c
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/jzoffer/tree/MirrorOfBinaryTree.java
@@ -0,0 +1,36 @@
+package org.wcong.test.algorithm.jzoffer.tree;
+
+import org.wcong.test.algorithm.jzoffer.util.Tree;
+import org.wcong.test.algorithm.jzoffer.util.TreeNode;
+
+/**
+ * test for binary tree
+ *
+ * give a binary tree return a mirror of it,left to right and right to left
+ *
+ * @author wcong
+ * @since 2017/3/26
+ */
+public class MirrorOfBinaryTree {
+
+ public static void main(String[] args) {
+
+ }
+
+ public static void mirrorOfBinaryTree(Tree tree) {
+ mirrorOfNode(tree.root);
+ }
+
+ private static void mirrorOfNode(TreeNode treeNode) {
+ if (treeNode == null) {
+ return;
+ }
+ TreeNode temp = treeNode.left;
+ treeNode.left = treeNode.right;
+ treeNode.right = temp;
+ mirrorOfNode(treeNode.left);
+ mirrorOfNode(treeNode.right);
+
+ }
+
+}
diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/tree/PrintBinaryTreeTopDown.java b/src/main/java/org/wcong/test/algorithm/jzoffer/tree/PrintBinaryTreeTopDown.java
new file mode 100644
index 0000000..359076d
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/jzoffer/tree/PrintBinaryTreeTopDown.java
@@ -0,0 +1,39 @@
+package org.wcong.test.algorithm.jzoffer.tree;
+
+import org.wcong.test.algorithm.jzoffer.util.Tree;
+import org.wcong.test.algorithm.jzoffer.util.TreeNode;
+
+import java.util.LinkedList;
+import java.util.Queue;
+
+/**
+ * test for binary tree
+ *
+ * @author wcong
+ * @since 2017/3/26
+ */
+public class PrintBinaryTreeTopDown {
+
+ public static void main(String[] args) {
+
+ }
+
+ public static void printTreeTopDown(Tree tree) {
+ if (tree == null || tree.root == null) {
+ return;
+ }
+ Queue treeNodeQueue = new LinkedList<>();
+ treeNodeQueue.add(tree.root);
+ while (!treeNodeQueue.isEmpty()) {
+ TreeNode node = treeNodeQueue.poll();
+ System.out.println(node.value);
+ if (node.left != null) {
+ treeNodeQueue.add(node.left);
+ }
+ if (node.right != null) {
+ treeNodeQueue.add(node.right);
+ }
+ }
+ }
+
+}
diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/util/BuildLinkedList.java b/src/main/java/org/wcong/test/algorithm/jzoffer/util/BuildLinkedList.java
new file mode 100644
index 0000000..df220a9
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/jzoffer/util/BuildLinkedList.java
@@ -0,0 +1,23 @@
+package org.wcong.test.algorithm.jzoffer.util;
+
+/**
+ * @author wcong
+ * @since 2017/3/26
+ */
+public class BuildLinkedList {
+
+ public static LinkedList makeOne(int[] array) {
+ LinkedListNode root = new LinkedListNode();
+ LinkedList linkedList = new LinkedList();
+ linkedList.root = root;
+ root.value = array[0];
+ LinkedListNode parent = root;
+ for (int i = 1; i < array.length; i++) {
+ LinkedListNode node = new LinkedListNode();
+ node.value = array[i];
+ parent.next = node;
+ parent = node;
+ }
+ return linkedList;
+ }
+}
diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/util/BuildTree.java b/src/main/java/org/wcong/test/algorithm/jzoffer/util/BuildTree.java
new file mode 100644
index 0000000..c305073
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/jzoffer/util/BuildTree.java
@@ -0,0 +1,35 @@
+package org.wcong.test.algorithm.jzoffer.util;
+
+/**
+ * @author wcong
+ * @since 2017/3/26
+ */
+public class BuildTree {
+
+ public static Tree buildOne(int[] array) {
+ Tree tree = new Tree();
+ TreeNode treeNode = new TreeNode();
+ treeNode.value = array[0];
+ tree.root = treeNode;
+ buildTree(treeNode, array, 0);
+ return tree;
+ }
+
+ private static void buildTree(TreeNode treeNode, int[] array, int h) {
+ int leftNode = h * 2 + 1;
+ if (leftNode < array.length) {
+ TreeNode left = new TreeNode();
+ left.value = array[leftNode];
+ treeNode.left = left;
+ buildTree(left, array, leftNode);
+ }
+ int rightNode = h * 2 + 2;
+ if (rightNode < array.length) {
+ TreeNode right = new TreeNode();
+ right.value = array[rightNode];
+ treeNode.right = right;
+ buildTree(right, array, rightNode);
+ }
+ }
+
+}
diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/util/ComplexListNode.java b/src/main/java/org/wcong/test/algorithm/jzoffer/util/ComplexListNode.java
new file mode 100644
index 0000000..a3a19d1
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/jzoffer/util/ComplexListNode.java
@@ -0,0 +1,17 @@
+package org.wcong.test.algorithm.jzoffer.util;
+
+/**
+ * @author wcong
+ * @since 2017/3/26
+ */
+public class ComplexListNode {
+ public int value;
+
+ public ComplexListNode next;
+
+ public ComplexListNode other;
+
+ public String toString() {
+ return String.valueOf(value);
+ }
+}
diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/util/LinkedList.java b/src/main/java/org/wcong/test/algorithm/jzoffer/util/LinkedList.java
new file mode 100644
index 0000000..d1bfc2a
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/jzoffer/util/LinkedList.java
@@ -0,0 +1,32 @@
+package org.wcong.test.algorithm.jzoffer.util;
+
+/**
+ * @author wcong
+ * @since 2017/3/26
+ */
+public class LinkedList {
+
+ public LinkedListNode root;
+
+ public boolean equal(LinkedList other) {
+ if (other == null) {
+ return false;
+ }
+ LinkedListNode otherNode = other.root;
+ LinkedListNode thisNode = root;
+ while (true) {
+ if ((otherNode == null && thisNode == null) || (otherNode != null && thisNode != null
+ && thisNode.value == otherNode.value)) {
+ if (otherNode == null) {
+ break;
+ }
+ otherNode = otherNode.next;
+ thisNode = thisNode.next;
+ } else {
+ return false;
+ }
+ }
+ return true;
+ }
+
+}
diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/util/LinkedListNode.java b/src/main/java/org/wcong/test/algorithm/jzoffer/util/LinkedListNode.java
new file mode 100644
index 0000000..aa87b1a
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/jzoffer/util/LinkedListNode.java
@@ -0,0 +1,17 @@
+package org.wcong.test.algorithm.jzoffer.util;
+
+/**
+ * @author wcong
+ * @since 2017/3/26
+ */
+public class LinkedListNode {
+
+ public int value;
+
+ public LinkedListNode next;
+
+ public String toString() {
+ return String.valueOf(value);
+ }
+
+}
diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/util/Tree.java b/src/main/java/org/wcong/test/algorithm/jzoffer/util/Tree.java
new file mode 100644
index 0000000..45ffe7b
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/jzoffer/util/Tree.java
@@ -0,0 +1,11 @@
+package org.wcong.test.algorithm.jzoffer.util;
+
+/**
+ * @author wcong
+ * @since 2017/3/26
+ */
+public class Tree {
+
+ public TreeNode root;
+
+}
diff --git a/src/main/java/org/wcong/test/algorithm/jzoffer/util/TreeNode.java b/src/main/java/org/wcong/test/algorithm/jzoffer/util/TreeNode.java
new file mode 100644
index 0000000..00a12dc
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/jzoffer/util/TreeNode.java
@@ -0,0 +1,15 @@
+package org.wcong.test.algorithm.jzoffer.util;
+
+/**
+ * @author wcong
+ * @since 2017/3/26
+ */
+public class TreeNode {
+
+ public int value;
+
+ public TreeNode left;
+
+ public TreeNode right;
+
+}
diff --git a/src/main/java/org/wcong/test/algorithm/leetcode/array/Candy.java b/src/main/java/org/wcong/test/algorithm/leetcode/array/Candy.java
new file mode 100644
index 0000000..ee49783
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/leetcode/array/Candy.java
@@ -0,0 +1,47 @@
+package org.wcong.test.algorithm.leetcode.array;
+
+/**
+ * There are N children standing in a line. Each child is assigned a rating value.
+ * You are giving candies to these children subjected to the following requirements:
+ * 1. Each child must have at least one candy.
+ * 2. Children with a higher rating get more candies than their neighbors.
+ * What is the minimum candies you must give?
+ *
+ * @author wcong
+ * @since 19/06/2017
+ */
+public class Candy {
+ public int candy(int[] ratings) {
+ int candies = 1;
+ int[] candy = new int[ratings.length];
+ candy[0] = 1;
+ for (int i = 1; i < ratings.length; i++) {
+ if (ratings[i] > ratings[i - 1]) {
+ candy[i] = candy[i - 1] + 1;
+ candies += candy[i];
+ } else if (ratings[i] < ratings[i - 1]) {
+ int lastIndex = i;
+ int lastRating = ratings[i];
+ while (lastIndex + 1 < ratings.length && lastRating > ratings[lastIndex + 1]) {
+ lastIndex += 1;
+ lastRating = ratings[lastIndex];
+ }
+ int num = 1;
+ for (int j = lastIndex; j >= i; j--) {
+ candy[j] = num;
+ candies += num;
+ num += 1;
+ }
+ if (candy[i - 1] < num) {
+ candies += num - candy[i - 1];
+ candy[i - 1] = num;
+ }
+ i = lastIndex;
+ } else {
+ candy[i] = 1;
+ candies += 1;
+ }
+ }
+ return candies;
+ }
+}
diff --git a/src/main/java/org/wcong/test/algorithm/leetcode/array/CreateMaximumNumber.java b/src/main/java/org/wcong/test/algorithm/leetcode/array/CreateMaximumNumber.java
new file mode 100644
index 0000000..69d1768
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/leetcode/array/CreateMaximumNumber.java
@@ -0,0 +1,126 @@
+package org.wcong.test.algorithm.leetcode.array;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Given two arrays of length m and n with digits 0-9 representing two numbers.
+ * Create the maximum number of length k <= m + n from digits of the two.
+ * The relative order of the digits from the same array must be preserved.
+ * Return an array of the k digits.
+ * You should try to optimize your time and space complexity
+ *
+ * @author wcong
+ * @since 13/06/2017
+ */
+public class CreateMaximumNumber {
+
+ private int[] maxNumber;
+
+ public int[] maxNumberBruteForce(int[] nums1, int[] nums2, int k) {
+ int total = nums1.length + nums2.length;
+ k = total > k ? k : total;
+ maxNumber = new int[k];
+ iterateMaxNumber(nums1, 0, nums2, 0, new int[k], k);
+ return maxNumber;
+ }
+
+ private void iterateMaxNumber(int[] nums1, int index1, int[] nums2, int index2, int[] number, int left) {
+ if (index1 >= nums1.length && index2 >= nums2.length && left > 0) {
+ return;
+ }
+ if (left <= 0) {
+ if (arrayCompare(number, maxNumber)) {
+ maxNumber = Arrays.copyOf(number, number.length);
+ }
+ return;
+ }
+ if (index1 < nums1.length) {
+ number[number.length - left] = nums1[index1];
+ iterateMaxNumber(nums1, index1 + 1, nums2, index2, number, left - 1);
+ iterateMaxNumber(nums1, index1 + 1, nums2, index2, number, left);
+ }
+ if (index2 < nums2.length) {
+ number[number.length - left] = nums2[index2];
+ iterateMaxNumber(nums1, index1, nums2, index2 + 1, number, left - 1);
+ iterateMaxNumber(nums1, index1, nums2, index2 + 1, number, left);
+ }
+ }
+
+ private boolean arrayCompare(int[] array1, int[] array2) {
+ for (int i = 0; i < array2.length; i++) {
+ if (array1[i] > array2[i]) {
+ return true;
+ } else if (array1[i] < array2[i]) {
+ return false;
+ }
+ }
+ return false;
+ }
+
+ static class Index {
+ public Index(boolean first, int index) {
+ this.first = first;
+ this.index = index;
+ }
+
+ boolean first = false;
+ int index = 0;
+ }
+
+ public int[] maxNumberGreed(int[] nums1, int[] nums2, int k) {
+ int total = nums1.length + nums2.length;
+ k = total > k ? k : total;
+ maxNumber = new int[k];
+ maxNumberGreed(nums1, 0, nums2, 0, k, new int[k]);
+ return maxNumber;
+ }
+
+ private void maxNumberGreed(int[] nums1, int index1, int[] nums2, int index2, int left, int[] current) {
+ if (left <= 0) {
+ if (arrayCompare(current, maxNumber)) {
+ maxNumber = Arrays.copyOf(current, current.length);
+ }
+ return;
+ }
+ List maxIndexList = findMaxIndex(nums1, index1, nums2, index2, left);
+ for (Index index : maxIndexList) {
+ if (index.first) {
+ current[current.length - left] = nums1[index.index];
+ maxNumberGreed(nums1, index.index + 1, nums2, index2, left - 1, current);
+ } else {
+ current[current.length - left] = nums2[index.index];
+ maxNumberGreed(nums1, index1, nums2, index.index + 1, left - 1, current);
+ }
+ }
+ }
+
+ private List findMaxIndex(int[] nums1, int index1, int[] nums2, int index2, int left) {
+ List maxList = new ArrayList<>();
+ int firstEnd = nums1.length - left + nums2.length - index2;
+ firstEnd = firstEnd >= nums1.length ? nums1.length - 1 : firstEnd;
+ int max = 0;
+ for (int i = index1; i <= firstEnd; i++) {
+ if (nums1[i] > max) {
+ maxList.clear();
+ maxList.add(new Index(true, i));
+ max = nums1[i];
+ } else if (nums1[i] == max) {
+ maxList.add(new Index(true, i));
+ }
+ }
+ int secondEnd = nums2.length - left + nums1.length - index1;
+ secondEnd = secondEnd >= nums2.length ? nums2.length - 1 : secondEnd;
+ for (int i = index2; i <= secondEnd; i++) {
+ if (nums2[i] > max) {
+ maxList.clear();
+ maxList.add(new Index(false, i));
+ max = nums2[i];
+ } else if (nums2[i] == max) {
+ maxList.add(new Index(false, i));
+ }
+ }
+ return maxList;
+ }
+}
diff --git a/src/main/java/org/wcong/test/algorithm/leetcode/array/MaxPointsOnALine.java b/src/main/java/org/wcong/test/algorithm/leetcode/array/MaxPointsOnALine.java
new file mode 100644
index 0000000..2db32fd
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/leetcode/array/MaxPointsOnALine.java
@@ -0,0 +1,162 @@
+package org.wcong.test.algorithm.leetcode.array;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Given n points on a 2D plane
+ * find the maximum number of points that lie on the same straight line.
+ *
+ * @author wcong
+ * @since 10/05/2017
+ */
+public class MaxPointsOnALine {
+
+ public int maxPointsBruteForce(Point[] points) {
+ if (points == null) {
+ return 0;
+ }
+ if (points.length < 2) {
+ return points.length;
+ }
+ int maxPoints = 0;
+ for (int firstIndex = 0; firstIndex < points.length; firstIndex++) {
+ for (int secondIndex = firstIndex + 1; secondIndex < points.length; secondIndex++) {
+ Point firstPoint = points[firstIndex];
+ Point secondPoint = points[secondIndex];
+ double angel = 0;
+ if (firstPoint.y != secondPoint.y) {
+ angel = firstPoint.x > secondPoint.x ?
+ (firstPoint.x - secondPoint.x) / (firstPoint.y - secondPoint.y) :
+ (secondPoint.x - firstPoint.x) / (secondPoint.y - firstPoint.y);
+ }
+ int pointsNum = 2;
+ for (int leftIndex = secondIndex + 1; leftIndex < points.length; leftIndex++) {
+ Point nextPoint = points[leftIndex];
+ if (firstPoint.y == nextPoint.y) {
+ if (firstPoint.y == secondPoint.y) {
+ pointsNum += 1;
+ }
+ continue;
+ }
+ double nextAngel = firstPoint.x > nextPoint.x ?
+ (firstPoint.x - nextPoint.x) / (firstPoint.y - nextPoint.y) :
+ (nextPoint.x - firstPoint.x) / (nextPoint.y - firstPoint.y);
+ if (angel == nextAngel) {
+ pointsNum += 1;
+ }
+ }
+ if (pointsNum > maxPoints) {
+ maxPoints = pointsNum;
+ }
+ }
+ }
+ return maxPoints;
+ }
+
+ static class MyPoint {
+ Point point;
+
+ String key;
+
+ int count;
+ }
+
+ public int maxPointsDp(Point[] points) {
+ if (points == null) {
+ return 0;
+ }
+ if (points.length < 2) {
+ return points.length;
+ }
+ Map pointCount = new HashMap<>();
+ for (Point point : points) {
+ String key = point.x + "_" + point.y;
+ if (pointCount.containsKey(key)) {
+ pointCount.get(key).count += 1;
+ } else {
+ MyPoint myPoint = new MyPoint();
+ myPoint.point = point;
+ myPoint.key = key;
+ myPoint.count = 1;
+ pointCount.put(key, myPoint);
+ }
+ }
+ List myPointList = new ArrayList<>(pointCount.values());
+ if( myPointList.size()==1 ){
+ return myPointList.get(0).count;
+ }
+ Set usedPoints = new HashSet<>();
+ int maxPoints = 0;
+ for (int firstIndex = 0; firstIndex < myPointList.size(); firstIndex++) {
+ for (int secondIndex = firstIndex + 1; secondIndex < myPointList.size(); secondIndex++) {
+ MyPoint firstPoint = myPointList.get(firstIndex);
+ MyPoint secondPoint = myPointList.get(secondIndex);
+ if (usedPoints.contains(firstIndex + "_" + secondIndex)) {
+ continue;
+ }
+ double angel = 0;
+ if (firstPoint.point.y != secondPoint.point.y) {
+ angel = firstPoint.point.x > secondPoint.point.x ?
+ (firstPoint.point.x - secondPoint.point.x) / (double)(firstPoint.point.y - secondPoint.point.y) :
+ (secondPoint.point.x - firstPoint.point.x) / (double)(secondPoint.point.y - firstPoint.point.y);
+ }
+ int pointsNum = firstPoint.count + secondPoint.count;
+ List sameIndex = new LinkedList<>();
+ for (int leftIndex = secondIndex + 1; leftIndex < myPointList.size(); leftIndex++) {
+ if (usedPoints.contains(secondIndex + "_" + leftIndex)) {
+ continue;
+ }
+ MyPoint nextPoint = myPointList.get(leftIndex);
+ if (firstPoint.point.y == nextPoint.point.y) {
+ if (firstPoint.point.y == secondPoint.point.y) {
+ for (Integer lastIndex : sameIndex) {
+ usedPoints.add(lastIndex + "_" + leftIndex);
+ }
+ sameIndex.add(leftIndex);
+ pointsNum += nextPoint.count;
+ }
+ continue;
+ }
+ double nextAngel = firstPoint.point.x > nextPoint.point.x ?
+ (firstPoint.point.x - nextPoint.point.x) / (double)(firstPoint.point.y - nextPoint.point.y) :
+ (nextPoint.point.x - firstPoint.point.x) / (double)(nextPoint.point.y - firstPoint.point.y);
+ if (angel == nextAngel) {
+ for (Integer lastIndex : sameIndex) {
+ usedPoints.add(lastIndex + "_" + leftIndex);
+ }
+ sameIndex.add(leftIndex);
+ pointsNum += nextPoint.count;
+ }
+ }
+
+ if (pointsNum > maxPoints) {
+ maxPoints = pointsNum;
+ }
+ }
+ }
+ return maxPoints;
+ }
+
+ public static class Point {
+ int x;
+
+ int y;
+
+ Point() {
+ x = 0;
+ y = 0;
+ }
+
+ public Point(int a, int b) {
+ x = a;
+ y = b;
+ }
+ }
+
+}
diff --git a/src/main/java/org/wcong/test/algorithm/leetcode/array/MedianOfTwoSortedArray.java b/src/main/java/org/wcong/test/algorithm/leetcode/array/MedianOfTwoSortedArray.java
new file mode 100644
index 0000000..bdb6a74
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/leetcode/array/MedianOfTwoSortedArray.java
@@ -0,0 +1,52 @@
+package org.wcong.test.algorithm.leetcode.array;
+
+/**
+ * There are two sorted arrays nums1 and nums2 of size m and n respectively.
+ * Find the median of the two sorted arrays.
+ * The overall run time complexity should be O(log (m+n)).
+ * ......*.......
+ * .....*......
+ *
+ * @author wcong
+ * @since 11/05/2017
+ */
+public class MedianOfTwoSortedArray {
+ public double findMedianSortedArrays(int[] nums1, int[] nums2) {
+ boolean isOdd = ((nums1.length + nums2.length) & 1) == 1;
+ int middle = (nums1.length + nums2.length) >> 1;
+ int nums1Start = 0;
+ int nums1End = nums1.length - 1;
+ int nums2Start = 0;
+ int nums2End = nums2.length - 1;
+ while (true) {
+ int nums1Middle = nums1Start + (nums1End - nums1Start) / 2;
+ int nums2Middle = nums2Start + (nums2End - nums2Start) / 2;
+ int currentPosition = nums1Middle + nums2Middle;
+ if (nums1[nums1Middle] == nums2[nums2Middle]) {
+ if (currentPosition == middle) {
+ break;
+ } else if (currentPosition < middle) {
+ nums1Start = nums1Middle;
+ nums2Start = nums2Middle;
+ } else {
+ nums1End = nums1Middle;
+ nums2End = nums2Middle;
+ }
+ } else if (nums1[nums1Middle] < nums2[nums2Middle]) {
+ nums2End = nums2Middle;
+ nums1Start = nums1Middle;
+ } else {
+ nums1End = nums1Middle;
+ nums2Start = nums2Middle;
+ }
+ if (nums1End == nums1Start && nums2End == nums2Start) {
+ break;
+ }
+ }
+ if (isOdd) {
+ return nums1[nums1End] > nums2[nums2End] ? nums1[nums1End] : nums2[nums2End];
+ } else {
+ return ((double) (nums1[nums1End] + nums2[nums2End])) / 2;
+ }
+ }
+}
diff --git a/src/main/java/org/wcong/test/algorithm/leetcode/array/NumbersOfIslands.java b/src/main/java/org/wcong/test/algorithm/leetcode/array/NumbersOfIslands.java
new file mode 100644
index 0000000..7263b6f
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/leetcode/array/NumbersOfIslands.java
@@ -0,0 +1,44 @@
+package org.wcong.test.algorithm.leetcode.array;
+
+/**
+ * Given a 2d grid map of '1's (land) and '0's (water), count the number of islands.
+ * An island is surrounded by water and is formed by connecting adjacent lands horizontally or vertically.
+ * You may assume all four edges of the grid are all surrounded by water.
+ *
+ * @author wcong
+ * @since 09/05/2017
+ */
+public class NumbersOfIslands {
+ public int numIslandsBruteForce(char[][] grid) {
+ int nums = 0;
+ for (int row = 0; row < grid.length; row++) {
+ for (int column = 0; column < grid[row].length; column++) {
+ if (grid[row][column] == '1') {
+ nums += 1;
+ elimateLand(grid, row, column);
+ }
+ }
+ }
+ return nums;
+ }
+
+ private void elimateLand(char[][] grid, int row, int column) {
+ if (grid[row][column] == '0') {
+ return;
+ }
+ grid[row][column] = '0';
+ if (row > 0) {
+ elimateLand(grid, row - 1, column);
+ }
+ if (column > 0) {
+ elimateLand(grid, row, column - 1);
+ }
+ if (row < grid.length - 1) {
+ elimateLand(grid, row + 1, column);
+ }
+ if (column < grid[row].length - 1) {
+ elimateLand(grid, row, column + 1);
+ }
+ }
+
+}
diff --git a/src/main/java/org/wcong/test/algorithm/leetcode/array/ReversePairs.java b/src/main/java/org/wcong/test/algorithm/leetcode/array/ReversePairs.java
new file mode 100644
index 0000000..364fe77
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/leetcode/array/ReversePairs.java
@@ -0,0 +1,85 @@
+package org.wcong.test.algorithm.leetcode.array;
+
+import java.util.Arrays;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * Given an array nums
+ * we call (i, j) an important reverse pair if i < j and nums[i] > 2*nums[j].
+ * You need to return the number of important reverse pairs in the given array.
+ *
+ * @author wcong
+ * @since 04/05/2017
+ */
+public class ReversePairs {
+
+ public int reversePairsBruteForce(int[] nums) {
+ int pairs = 0;
+ for (int index = 0; index < nums.length; index++) {
+ for (int nextIndex = index + 1; nextIndex < nums.length; nextIndex++) {
+ if (nums[index] > 2 * nums[nextIndex]) {
+ pairs += 1;
+ }
+ }
+ }
+ return pairs;
+ }
+
+ public int reversePairsDivideAndConquer(int[] nums) {
+ return reversePairsDivideAndConquer(nums, 0, nums.length - 1);
+ }
+
+ private int reversePairsDivideAndConquer(int[] nums, int start, int end) {
+ if (start >= end) {
+ return 0;
+ }
+ int pairs = 0;
+ int middle = start + (end - start) / 2;
+ pairs += reversePairsDivideAndConquer(nums, start, middle);
+ pairs += reversePairsDivideAndConquer(nums, middle + 1, end);
+ int leftIndex = start;
+ for (int rightIndex = middle + 1; rightIndex <= end; rightIndex++) {
+ long currentNum = nums[rightIndex];
+ for (; leftIndex <= middle; leftIndex++) {
+ if (2 * currentNum < nums[leftIndex]) {
+ pairs += middle - leftIndex + 1;
+ break;
+ }
+ }
+ }
+
+ Arrays.sort(nums, start, end + 1);
+ return pairs;
+ }
+
+ public int reversePairsLiner(int[] nums) {
+ List sorted = new LinkedList<>();
+ int pairs = 0;
+ for (int soloNum : nums) {
+ pairs += countAndInsert(sorted, soloNum);
+ }
+ return pairs;
+ }
+
+ private int countAndInsert(List sorted, Integer num) {
+ if (sorted.isEmpty()) {
+ sorted.add(num);
+ return 0;
+ }
+ int pairsIndex = 0;
+ int insertIndex = 0;
+ for (int integer : sorted) {
+ if (integer < num) {
+ insertIndex += 1;
+ }
+ if (integer > 2 * (long) num) {
+ break;
+ }
+ pairsIndex += 1;
+ }
+ sorted.add(insertIndex, num);
+ return sorted.size() - 1 - pairsIndex;
+ }
+
+}
diff --git a/src/main/java/org/wcong/test/algorithm/leetcode/array/TwoSum.java b/src/main/java/org/wcong/test/algorithm/leetcode/array/TwoSum.java
new file mode 100644
index 0000000..d4c6ab9
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/leetcode/array/TwoSum.java
@@ -0,0 +1,18 @@
+package org.wcong.test.algorithm.leetcode.array;
+
+/**
+ * give a array of integer and a target,return the indices where two sum equals the target
+ * assume only one solution
+ * Created by wcong on 2017/4/5.
+ */
+public class TwoSum {
+
+ public static void main(String[] args) {
+
+ }
+
+ public static int[] indices(int[] array, int target) {
+ return null;
+ }
+
+}
diff --git a/src/main/java/org/wcong/test/algorithm/leetcode/dp/RegularExpressionMatching.java b/src/main/java/org/wcong/test/algorithm/leetcode/dp/RegularExpressionMatching.java
new file mode 100644
index 0000000..b9ac417
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/leetcode/dp/RegularExpressionMatching.java
@@ -0,0 +1,49 @@
+package org.wcong.test.algorithm.leetcode.dp;
+
+/**
+ * test for dynamic programming and string matching
+ *
+ * Implement regular expression matching with support for '.' and '*'.
+ * '.' Matches any single character.
+ * '*' Matches zero or more of the preceding element.
+ * The matching should cover the entire input string (not partial).
+ * The function prototype should be:
+ * bool isMatch(const char *s, const char *p)
+ * Created by wcong on 2017/3/27.
+ */
+public class RegularExpressionMatching {
+
+ public static void main(String[] args) {
+
+ }
+
+ public static boolean isMatch(String s, String pattern) {
+ if (s == null || s.isEmpty() || pattern == null || pattern.isEmpty()) {
+ return false;
+ }
+ boolean[][] result = new boolean[s.length() + 1][pattern.length() + 1];
+ result[0][0] = true;
+ for (int i = 0; i < pattern.length(); i++) {
+ if (pattern.charAt(i) == '*' && result[0][i - 1]) {
+ result[0][i + 1] = true;
+ }
+ }
+ for (int i = 0; i < s.length(); i++) {
+ for (int j = 0; j < pattern.length(); j++) {
+ if (pattern.charAt(j) == '.') {
+ result[i + 1][j + 1] = result[i][j];
+ } else if (pattern.charAt(j) != '*') {
+ result[i + 1][j + 1] = result[i][j] && (s.charAt(i) == pattern.charAt(j));
+ } else {
+ if (pattern.charAt(j - 1) != s.charAt(i) && pattern.charAt(j - 1) != '.') {
+ result[i + 1][j + 1] = result[i + 1][j - 1];
+ } else {
+ result[i + 1][j + 1] = (result[i + 1][j] || result[i][j + 1] || result[i + 1][j - 1]);
+ }
+ }
+ }
+ }
+ return result[s.length()][pattern.length()];
+ }
+
+}
diff --git a/src/main/java/org/wcong/test/algorithm/leetcode/dp/UniqueBinarySearchTree.java b/src/main/java/org/wcong/test/algorithm/leetcode/dp/UniqueBinarySearchTree.java
new file mode 100644
index 0000000..a0918d3
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/leetcode/dp/UniqueBinarySearchTree.java
@@ -0,0 +1,41 @@
+package org.wcong.test.algorithm.leetcode.dp;
+
+/**
+ * test for binary search tree and dynamic programing
+ *
+ * // Given n, how many structurally unique BST's (binary search trees) that store values 1...n?
+ *
+ * // For example,
+ * // Given n = 3, there are a total of 5 unique BST's.
+ *
+ * // 1 3 3 2 1
+ * // \ / / / \ \
+ * // 3 2 1 1 3 2
+ * // / / \ \
+ * // 2 1 2 3
+ * Created by wcong on 2017/3/27.
+ */
+public class UniqueBinarySearchTree {
+
+ public static void main(String[] args) {
+
+ }
+
+
+ public static int binarySearchTree(int n) {
+ if (n <= 0) {
+ return 0;
+ }
+ int[] rangeNum = new int[n];
+ rangeNum[0] = 1;
+ rangeNum[1] = 1;
+ for (int i = 2; i <= n; i++) {
+ for (int j = 1; j <= i; j++) {
+ rangeNum[i] += rangeNum[j - 1] * rangeNum[j - i];
+ }
+ }
+ return rangeNum[n];
+ }
+
+
+}
diff --git a/src/main/java/org/wcong/test/algorithm/leetcode/dp/WordBreak.java b/src/main/java/org/wcong/test/algorithm/leetcode/dp/WordBreak.java
new file mode 100644
index 0000000..6ee6eee
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/leetcode/dp/WordBreak.java
@@ -0,0 +1,50 @@
+package org.wcong.test.algorithm.leetcode.dp;
+
+/**
+ * test for dynamic programming
+ *
+ * // Given a non-empty string s and a dictionary wordDict containing a list of non-empty words,
+ * determine if s can be segmented into a space-separated sequence of one or more dictionary words.
+ * You may assume the dictionary does not contain duplicate words.
+ *
+ * // For example, given
+ * // s = "leetcode",
+ * // dict = ["leet", "code"].
+ *
+ * // Return true because "leetcode" can be segmented as "leet code".
+ * Created by wcong on 2017/3/27.
+ */
+public class WordBreak {
+
+ public static void main(String[] args) {
+
+ }
+
+ // suppose it has none blank char
+ public static boolean wordBreak(String s, String[] dict) {
+ if (dict == null || dict.length == 0 || s == null || s.length() == 0) {
+ return false;
+ }
+ boolean[] result = new boolean[s.length()];
+ result[0] = true;
+ for (int i = 0; i < s.length(); i++) {
+ for (int j = i; j >= 0; j--) {
+ if (isInDict(s.substring(j, i + 1), dict) && result[j]) {
+ result[i + 1] = true;
+ break;
+ }
+ }
+ }
+ return result[s.length()];
+ }
+
+
+ private static boolean isInDict(String s, String[] dict) {
+ for (String word : dict) {
+ if (word.equals(s)) {
+ return true;
+ }
+ }
+ return false;
+ }
+}
diff --git a/src/main/java/org/wcong/test/algorithm/leetcode/numbers/NumberToWords.java b/src/main/java/org/wcong/test/algorithm/leetcode/numbers/NumberToWords.java
new file mode 100644
index 0000000..3888218
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/leetcode/numbers/NumberToWords.java
@@ -0,0 +1,68 @@
+package org.wcong.test.algorithm.leetcode.numbers;
+
+/**
+ * Convert a non-negative integer to its english words representation.
+ * Given input is guaranteed to be less than 231 - 1.
+ * 123 -> "One Hundred Twenty Three"
+ * 12345 -> "Twelve Thousand Three Hundred Forty Five"
+ * 1234567 -> "One Million Two Hundred Thirty Four Thousand Five Hundred Sixty Seven"
+ *
+ * @author wcong
+ * @since 16/05/2017
+ */
+public class NumberToWords {
+
+ private static String[] LEVEL = new String[] { "", "Thousand", "Million", "Billion" };
+
+ private static String[] NUMBERS = new String[] { "Zero", "One", "Two", "Three", "Four", "Five", "Six", "Seven",
+ "Eight", "Nine", "Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen",
+ "Eighteen", "Nineteen" };
+
+ private static String[] TEN_LEVEL = new String[] { "", "", "Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy",
+ "Eighty", "Ninety" };
+
+ public String numberToWords(int num) {
+ if (num == 0) {
+ return "Zero";
+ }
+ String words = "";
+ int level = 0;
+ while (num > 0) {
+ String result = numberToWords(num % 1000, level);
+ if (words.length() > 0 && result.length() > 0) {
+ words = result + " " + words;
+ } else {
+ words = result + words;
+ }
+ num = num / 1000;
+ level += 1;
+ }
+ return words;
+ }
+
+ private String numberToWords(int num, int level) {
+ StringBuilder stringBuilder = new StringBuilder();
+ if (num >= 100) {
+ stringBuilder.append(NUMBERS[num / 100]).append(" ").append("Hundred");
+ num = num % 100;
+ }
+ if (num >= 20) {
+ if (stringBuilder.length() > 0) {
+ stringBuilder.append(" ");
+ }
+ stringBuilder.append(TEN_LEVEL[num / 10]);
+ num = num % 10;
+ }
+ if (num > 0) {
+ if (stringBuilder.length() > 0) {
+ stringBuilder.append(" ");
+ }
+ stringBuilder.append(NUMBERS[num]);
+ }
+ if (level > 0 && stringBuilder.length() > 0) {
+ stringBuilder.append(" ").append(LEVEL[level]);
+ }
+ return stringBuilder.toString();
+ }
+
+}
diff --git a/src/main/java/org/wcong/test/algorithm/leetcode/package-info.java b/src/main/java/org/wcong/test/algorithm/leetcode/package-info.java
new file mode 100644
index 0000000..3d36c64
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/leetcode/package-info.java
@@ -0,0 +1 @@
+//for leetcode
\ No newline at end of file
diff --git a/src/main/java/org/wcong/test/algorithm/leetcode/string/BestTimeBuySellStockIV.java b/src/main/java/org/wcong/test/algorithm/leetcode/string/BestTimeBuySellStockIV.java
new file mode 100644
index 0000000..c5b0250
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/leetcode/string/BestTimeBuySellStockIV.java
@@ -0,0 +1,78 @@
+package org.wcong.test.algorithm.leetcode.string;
+
+/**
+ * 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 k transactions.
+ * Note:
+ * You may not engage in multiple transactions at the same time
+ * (ie, you must sell the stock before you buy again).
+ *
+ * @author wcong
+ * @since 08/06/2017
+ */
+public class BestTimeBuySellStockIV {
+
+ private Integer maxProfit;
+
+ public int maxProfitBruteForce(int k, int[] prices) {
+ maxProfit = 0;
+ iterateOptions(k, 0, prices, false, 0, 0);
+ return maxProfit;
+ }
+
+ private void iterateOptions(int transactions, int index, int[] prices, boolean isBuy, int currentPrice, int currentProfit) {
+ if (index >= prices.length || transactions <= 0) {
+ if (currentProfit > maxProfit) {
+ maxProfit = currentProfit;
+ }
+ return;
+ }
+ if (!isBuy) {
+ iterateOptions(transactions, index + 1, prices, true, prices[index], currentProfit);
+ iterateOptions(transactions, index + 1, prices, false, currentPrice, currentProfit);
+ } else {
+ iterateOptions(transactions - 1, index + 1, prices, false, prices[index], currentProfit + prices[index] - currentPrice);
+ iterateOptions(transactions, index + 1, prices, true, currentPrice, currentProfit);
+ }
+ }
+
+
+ static class Result {
+ int profit = 0;
+ int transactions = 0;
+ }
+
+ public int maxProfitDp(int k, int[] prices) {
+ if (k <= 0 || prices.length == 0) {
+ return 0;
+ }
+ Result[] profits = new Result[prices.length];
+ profits[0] = new Result();
+ for (int i = 1; i < prices.length; i++) {
+ Result result = new Result();
+ result.profit = prices[i] - prices[0];
+ result.transactions = 1;
+ if (result.profit < 0) {
+ result.profit = 0;
+ result.transactions = 0;
+ }
+ for (int j = 1; j < i; j++) {
+ if (profits[j - 1].transactions + 1 > k) {
+ continue;
+ }
+ int profit = profits[j - 1].profit + prices[i] - prices[j];
+ if (profit > result.profit) {
+ result.profit = profit;
+ result.transactions = profits[j - 1].transactions + 1;
+ }
+ }
+ if (profits[i - 1].profit > result.profit) {
+ result.profit = profits[i - 1].profit;
+ result.transactions = profits[i - 1].transactions;
+ }
+ profits[i] = result;
+ }
+ return profits[prices.length - 1].profit;
+ }
+}
diff --git a/src/main/java/org/wcong/test/algorithm/leetcode/string/DecodeWays.java b/src/main/java/org/wcong/test/algorithm/leetcode/string/DecodeWays.java
new file mode 100644
index 0000000..71e5f14
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/leetcode/string/DecodeWays.java
@@ -0,0 +1,32 @@
+package org.wcong.test.algorithm.leetcode.string;
+
+import org.eclipse.core.runtime.Assert;
+
+/**
+ * string also a dynamic programming
+ * encode way,A->1,....,Z->26
+ * give a string of numbers,count all the ways can be decoded
+ * for example 12 can be decode two ways 1->A,2->B or 12->L
+ * Created by wcong on 2017/4/1.
+ */
+public class DecodeWays {
+
+ public static void main(String[] args) {
+ Assert.isTrue(decodeWays("123") == 3);
+ }
+
+ public static int decodeWays(String encode) {
+ int[] result = new int[encode.length() + 1];
+ result[0] = 1;
+ result[1] = 1;
+ for (int i = 1; i < encode.length(); i++) {
+ if (Integer.parseInt(encode.substring(i - 1, i + 1)) <= 26) {
+ result[i + 1] = result[i - 1] + result[i];
+ } else {
+ result[i + 1] = result[i];
+ }
+ }
+ return result[encode.length()];
+ }
+
+}
diff --git a/src/main/java/org/wcong/test/algorithm/leetcode/string/InterleavingString.java b/src/main/java/org/wcong/test/algorithm/leetcode/string/InterleavingString.java
new file mode 100644
index 0000000..6d03b21
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/leetcode/string/InterleavingString.java
@@ -0,0 +1,52 @@
+package org.wcong.test.algorithm.leetcode.string;
+
+/**
+ * Given s1, s2, s3
+ * find whether s3 is formed by the interleaving of s1 and s2.
+ * For example,
+ * Given:
+ * s1 = "aabcc",
+ * s2 = "dbbca",
+ * When s3 = "aadbbcbcac", return true.
+ * When s3 = "aadbbbaccc", return false.
+ *
+ * @author wcong
+ * @since 15/06/2017
+ */
+public class InterleavingString {
+ public boolean isInterleaveBruteForce(String s1, String s2, String s3) {
+ if (s1.length() + s2.length() != s3.length()) {
+ return false;
+ }
+ return isInterleaveBruteForce(s1, 0, s2, 0, s3, 0);
+ }
+
+ private boolean isInterleaveBruteForce(String s1, int index1, String s2, int index2, String s3, int index3) {
+ return (index3 < s3.length()
+ && index1 < s1.length()
+ && s3.charAt(index3) == s1.charAt(index1) &&
+ isInterleaveBruteForce(s1, index1 + 1, s2, index2, s3, index3 + 1))
+ || (index3 < s3.length()
+ && index2 < s2.length()
+ && s3.charAt(index3) == s2.charAt(index2)
+ && isInterleaveBruteForce(s1, index1, s2, index2 + 1, s3, index3 + 1))
+ || (index3 == s3.length() && index1 + index2 == s3.length());
+ }
+
+ public boolean isInterleaveDp(String s1, String s2, String s3) {
+ if (s1.length() + s2.length() != s3.length()) {
+ return false;
+ }
+ boolean[][] matchMatrix = new boolean[s1.length() + 1][s2.length() + 1];
+ matchMatrix[0][0] = true;
+ matchMatrix[1][0] = s3.charAt(0) == s1.charAt(0);
+ matchMatrix[0][1] = s3.charAt(0) == s2.charAt(0);
+ for (int i = 1; i < s3.length(); i++) {
+ int length = i + 1;
+ for (int index1 = 0; index1 < length && index1 < s1.length() && length - index1 < s2.length(); index1++) {
+ matchMatrix[index1][length - index1] = s3.charAt(i) == s1.charAt(index1) && matchMatrix[index1][length - index1 - 1];
+ }
+ }
+ return matchMatrix[s1.length()][s2.length()];
+ }
+}
diff --git a/src/main/java/org/wcong/test/algorithm/leetcode/string/KthSmallestLexicographicalOrder.java b/src/main/java/org/wcong/test/algorithm/leetcode/string/KthSmallestLexicographicalOrder.java
new file mode 100644
index 0000000..a8fa2da
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/leetcode/string/KthSmallestLexicographicalOrder.java
@@ -0,0 +1,67 @@
+package org.wcong.test.algorithm.leetcode.string;
+
+import java.util.Arrays;
+
+/**
+ * Given integers n and k
+ * find the lexicographically k-th smallest integer in the range from 1 to n.
+ * Note: 1 ≤ k ≤ n ≤ 10^9.
+ * Example:
+ * Input: n: 13 k: 2
+ * Output:10
+ * Explanation:
+ * The lexicographical order is [1, 10, 11, 12, 13, 2, 3, 4, 5, 6, 7, 8, 9],
+ * so the second smallest number is 10.
+ *
+ * @author wcong
+ * @since 05/06/2017
+ */
+public class KthSmallestLexicographicalOrder {
+
+ public int findKthNumberBruteForce(int n, int k) {
+ String[] numbers = new String[n];
+ for (int i = 1; i <= n; i++) {
+ numbers[i - 1] = String.valueOf(i);
+ }
+ Arrays.sort(numbers);
+ return Integer.parseInt(numbers[k - 1]);
+ }
+
+ public static class Result {
+ boolean found = false;
+ int number = 1;
+ int order = 1;
+ }
+
+ public int findKthNumberGreed(int n, int k) {
+ Result result = new Result();
+ findKthNumberGreed(n, k, result);
+ return result.number;
+ }
+
+ private void findKthNumberGreed(int n, int k, Result result) {
+ int number = result.number;
+ if (result.found) {
+ return;
+ }
+ for (int i = 0; i < 9; i++) {
+ if (result.order < k && number * 10 <= n) {
+ result.number = number * 10;
+ result.order += 1;
+ result.found = result.order == k;
+ findKthNumberGreed(n, k, result);
+ }
+ if (result.found) {
+ return;
+ }
+ number += 1;
+ if (number > n) {
+ return;
+ }
+ result.order += 1;
+ result.number = number;
+ result.found = result.order == k;
+ }
+ }
+
+}
diff --git a/src/main/java/org/wcong/test/algorithm/leetcode/string/LongestSubStringContainKDistinctWord.java b/src/main/java/org/wcong/test/algorithm/leetcode/string/LongestSubStringContainKDistinctWord.java
new file mode 100644
index 0000000..0607c6a
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/leetcode/string/LongestSubStringContainKDistinctWord.java
@@ -0,0 +1,40 @@
+package org.wcong.test.algorithm.leetcode.string;
+
+import org.springframework.util.Assert;
+
+/**
+ * give a string find the longest sub string that contains k distinct word
+ * for example cecba k =2 longest sub string is ece
+ * Created by wcong on 2017/4/1.
+ */
+public class LongestSubStringContainKDistinctWord {
+
+ public static void main(String[] args) {
+ Assert.isTrue(subString("cecba", 2).equals("cec"));
+ }
+
+ public static String subString(String a, int k) {
+ int longestStart = 0;
+ int longestEnd = 0;
+ int start = 0;
+ int distinct = 0;
+ for (int i = 0; i < a.length(); i++) {
+ if (!a.substring(start, i).contains(a.substring(i, i + 1))) {
+ distinct += 1;
+ }
+ if (distinct == k && i - start > longestEnd - longestStart) {
+ longestEnd = i;
+ longestStart = start;
+ } else if (distinct > k) {
+ while (start <= i) {
+ start = start + 1;
+ if (!a.substring(start + 1, i + 1).contains(a.substring(start, start + 1))) {
+ break;
+ }
+ }
+ }
+ }
+ return a.substring(longestStart, longestEnd + 1);
+ }
+
+}
diff --git a/src/main/java/org/wcong/test/algorithm/leetcode/string/LongestValidParentheses.java b/src/main/java/org/wcong/test/algorithm/leetcode/string/LongestValidParentheses.java
new file mode 100644
index 0000000..5dbe8be
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/leetcode/string/LongestValidParentheses.java
@@ -0,0 +1,82 @@
+package org.wcong.test.algorithm.leetcode.string;
+
+import java.util.Stack;
+
+/**
+ * Given a string containing just the characters '(' and ')',
+ * find the length of the longest valid (well-formed) parentheses substring.
+ * For "(()", the longest valid parentheses substring is "()", which has length = 2.
+ * Another example is ")()())", where the longest valid parentheses substring is "()()", which has length = 4.
+ *
+ * @author wcong
+ * @since 03/06/2017
+ */
+public class LongestValidParentheses {
+ public int longestValidParenthesesBruteForce(String s) {
+ if (s == null || s.length() == 0) {
+ return 0;
+ }
+ int maxLength = 0;
+ for (int start = 0; start < s.length(); start++) {
+ for (int end = start + 1; end < s.length(); end++) {
+ if (isValidParentheses(s, start, end)) {
+ int length = end - start + 1;
+ if (length > maxLength) {
+ maxLength = length;
+ }
+ }
+ }
+ }
+ return maxLength;
+ }
+
+ private boolean isValidParentheses(String s, int start, int end) {
+ Stack characterStack = new Stack<>();
+ for (int i = start; i <= end; i++) {
+ if (s.charAt(i) == '(') {
+ characterStack.push('(');
+ } else if (s.charAt(i) == ')' && !characterStack.isEmpty() && characterStack.peek() == '(') {
+ characterStack.pop();
+ } else {
+ return false;
+ }
+ }
+ return characterStack.isEmpty();
+ }
+
+ public int longestValidParenthesesGreed(String s) {
+ int maxLength = 0;
+ int leftNum = 0;
+ int rightNum = 0;
+ int startIndex = 0;
+ Stack characterStack = new Stack<>();
+ for (int i = 0; i < s.length(); i++) {
+ if (s.charAt(i) == '(') {
+ characterStack.push(i);
+ leftNum += 1;
+ } else {
+ if (characterStack.isEmpty()) {
+ leftNum = 0;
+ rightNum = 0;
+ startIndex = i + 1;
+ } else {
+ characterStack.peek();
+ rightNum += 1;
+ characterStack.pop();
+ if (characterStack.isEmpty()) {
+ int length = i - startIndex + 1;
+ if (length > maxLength) {
+ maxLength = length;
+ }
+ leftNum = 0;
+ rightNum = 0;
+ }
+ }
+ }
+ }
+ if (leftNum >= rightNum && rightNum * 2 > maxLength) {
+ maxLength = rightNum * 2;
+ }
+ return maxLength;
+ }
+}
diff --git a/src/main/java/org/wcong/test/algorithm/leetcode/string/PalindromePartitioning2.java b/src/main/java/org/wcong/test/algorithm/leetcode/string/PalindromePartitioning2.java
new file mode 100644
index 0000000..ff9f155
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/leetcode/string/PalindromePartitioning2.java
@@ -0,0 +1,48 @@
+package org.wcong.test.algorithm.leetcode.string;
+
+/**
+ * Given a string s,
+ * partition s such that every substring of the partition is a palindrome.
+ * Return the minimum cuts needed for a palindrome partitioning of s.
+ * For example, given s = "aab",
+ * Return 1 since the palindrome partitioning ["aa","b"] could be produced using 1 cut.
+ *
+ * @author wcong
+ * @since 07/06/2017
+ */
+public class PalindromePartitioning2 {
+
+ boolean[][] palindromeMatrix;
+
+ public int minCutDp(String s) {
+ int[] minCut = new int[s.length()];
+ palindromeMatrix = new boolean[s.length()][s.length()];
+ minCut[0] = 0;
+ for (int i = 1; i < s.length(); i++) {
+ if (isPalindrome(s, 0, i)) {
+ minCut[i] = 0;
+ } else {
+ int minCutNum = minCut[i - 1] + 1;
+ for (int j = 1; j < i; j++) {
+ if (isPalindrome(s, j, i)) {
+ int cutNum = minCut[j - 1] + 1;
+ if (cutNum < minCutNum) {
+ minCutNum = cutNum;
+ }
+ }
+ }
+ minCut[i] = minCutNum;
+ }
+ }
+ return minCut[s.length() - 1];
+ }
+
+ private boolean isPalindrome(String s, int start, int end) {
+ if (s.charAt(start) == s.charAt(end) && (start + 1 >= end - 1 || palindromeMatrix[start + 1][end - 1])) {
+ palindromeMatrix[start][end] = true;
+ return true;
+ } else {
+ return false;
+ }
+ }
+}
diff --git a/src/main/java/org/wcong/test/algorithm/leetcode/string/ShortestPalindrome.java b/src/main/java/org/wcong/test/algorithm/leetcode/string/ShortestPalindrome.java
new file mode 100644
index 0000000..35c5738
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/leetcode/string/ShortestPalindrome.java
@@ -0,0 +1,41 @@
+package org.wcong.test.algorithm.leetcode.string;
+
+/**
+ * Given a string S
+ * you are allowed to convert it to a palindrome by adding characters in front of it.
+ * Find and return the shortest palindrome you can find by performing this transformation.
+ * For example:
+ * Given "aacecaaa", return "aaacecaaa".
+ * Given "abcd", return "dcbabcd".
+ *
+ * @author wcong
+ * @since 07/06/2017
+ */
+public class ShortestPalindrome {
+
+ public String shortestPalindromeBruteForce(String s) {
+ StringBuilder insert = new StringBuilder();
+ int end = s.length() - 1;
+ while (end > 0) {
+ if (isPalindrome(s, 0, end)) {
+ break;
+ } else {
+ insert.append(s.charAt(end));
+ end -= 1;
+ }
+ }
+ return insert + s;
+ }
+
+ private boolean isPalindrome(String s, int start, int end) {
+ while (start <= end) {
+ if (s.charAt(start) == s.charAt(end)) {
+ start += 1;
+ end -= 1;
+ } else {
+ return false;
+ }
+ }
+ return true;
+ }
+}
diff --git a/src/main/java/org/wcong/test/algorithm/leetcode/string/StringMultiply.java b/src/main/java/org/wcong/test/algorithm/leetcode/string/StringMultiply.java
new file mode 100644
index 0000000..eae531c
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/leetcode/string/StringMultiply.java
@@ -0,0 +1,18 @@
+package org.wcong.test.algorithm.leetcode.string;
+
+/**
+ * give two string of integer, calculate the product of them
+ * Created by wcong on 2017/4/1.
+ */
+public class StringMultiply {
+
+ public static void main(String[] args) {
+
+ }
+
+ public static String multiply(String a, String b) {
+ return null;
+ }
+
+}
+
diff --git a/src/main/java/org/wcong/test/algorithm/leetcode/string/StrongPassword.java b/src/main/java/org/wcong/test/algorithm/leetcode/string/StrongPassword.java
new file mode 100644
index 0000000..9788d58
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/leetcode/string/StrongPassword.java
@@ -0,0 +1,22 @@
+package org.wcong.test.algorithm.leetcode.string;
+
+/**
+ * A password is considered strong if below conditions are all met:
+ * 1. It has at least 6 characters and at most 20 characters.
+ * 2. It must contain at least one lowercase letter, at least one uppercase letter, and at least one digit.
+ * 3. It must NOT contain three repeating characters in a row ("...aaa..." is weak, but "...aa...a..." is strong, assuming other conditions are met).
+ * Write a function strongPasswordChecker(s), that takes a string s as input, and return the MINIMUM change required to make s a strong password. If s is already strong, return 0.
+ * Insertion, deletion or replace of any one character are all considered as one change.
+ *
+ * @author wcong
+ * @since 07/05/2017
+ */
+public class StrongPassword {
+
+ public int strongPasswordDP(String s) {
+ int[][] distance = new int[s.length()][s.length()];
+
+ return distance[s.length()][s.length()];
+ }
+
+}
diff --git a/src/main/java/org/wcong/test/algorithm/leetcode/string/SubstringWithConcatenationAllWords.java b/src/main/java/org/wcong/test/algorithm/leetcode/string/SubstringWithConcatenationAllWords.java
new file mode 100644
index 0000000..097cc02
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/leetcode/string/SubstringWithConcatenationAllWords.java
@@ -0,0 +1,67 @@
+package org.wcong.test.algorithm.leetcode.string;
+
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * You are given a string, s, and a list of words, words,
+ * that are all of the same length.
+ * Find all starting indices of substring(s) in s
+ * that is a concatenation of each word in words
+ * exactly once and without any intervening characters.
+ * For example, given:
+ * s: "barfoothefoobarman"
+ * words: ["foo", "bar"]
+ * You should return the indices: [0,9].
+ * (order does not matter).
+ *
+ * @author wcong
+ * @since 17/05/2017
+ */
+public class SubstringWithConcatenationAllWords {
+
+ public List findSubstringBruteForce(String s, String[] words) {
+ List indices = new LinkedList<>();
+ if (words == null || words.length == 0) {
+ return indices;
+ }
+ int len = words[0].length();
+ Map map = new HashMap<>();
+ for (String word : words) {
+ if (map.containsKey(word)) {
+ map.put(word, map.get(word) + 1);
+ } else {
+ map.put(word, 1);
+ }
+ }
+ for (int index = 0; index < s.length(); index++) {
+ if (isConcatenation(s, index, new HashMap<>(map), len)) {
+ indices.add(index);
+ }
+ }
+ return indices;
+ }
+
+ private boolean isConcatenation(String s, int index, Map map, int len) {
+ if (map.isEmpty()) {
+ return true;
+ }
+ if (index + len > s.length()) {
+ return false;
+ }
+ String nextWord = s.substring(index, index + len);
+ Integer num = map.get(nextWord);
+ if (num == null) {
+ return false;
+ }
+ if (num == 1) {
+ map.remove(nextWord);
+ } else {
+ map.put(nextWord, num - 1);
+ }
+ return isConcatenation(s, index + len, map, len);
+ }
+
+}
diff --git a/src/main/java/org/wcong/test/algorithm/leetcode/string/TextJustifacation.java b/src/main/java/org/wcong/test/algorithm/leetcode/string/TextJustifacation.java
new file mode 100644
index 0000000..2f9657f
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/leetcode/string/TextJustifacation.java
@@ -0,0 +1,26 @@
+package org.wcong.test.algorithm.leetcode.string;
+
+import java.util.List;
+
+/**
+ * Given an array of words and a length L,
+ * format the text such that each line has exactly L characters and is fully (left and right) justified.
+ *
+ * You should pack your words in a greedy approach;
+ * that is, pack as many words as you can in each line.
+ * Pad extra spaces ' ' when necessary so that each line has exactly L characters.
+ *
+ * Extra spaces between words should be distributed as evenly as possible.
+ * If the number of spaces on a line do not divide evenly between words,
+ * the empty slots on the left will be assigned more spaces than the slots on the right.
+ *
+ * For the last line of text, it should be left justified and no extra space is inserted between words.
+ *
+ * @author wcong
+ * @since 05/05/2017
+ */
+public class TextJustifacation {
+ public List fullJustify(String[] words, int maxWidth) {
+ return null;
+ }
+}
diff --git a/src/main/java/org/wcong/test/algorithm/leetcode/string/WordBreak2.java b/src/main/java/org/wcong/test/algorithm/leetcode/string/WordBreak2.java
new file mode 100644
index 0000000..2ceb521
--- /dev/null
+++ b/src/main/java/org/wcong/test/algorithm/leetcode/string/WordBreak2.java
@@ -0,0 +1,89 @@
+package org.wcong.test.algorithm.leetcode.string;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Given a non-empty string s and a dictionary wordDict containing a list of non-empty words,
+ * add spaces in s to construct a sentence where each word is a valid dictionary word.
+ * You may assume the dictionary does not contain duplicate words.
+ * Return all such possible sentences.
+ * For example, given
+ * s = "catsanddog",
+ * dict = ["cat", "cats", "and", "sand", "dog"].
+ * A solution is ["cats and dog", "cat sand dog"].
+ *
+ * @author wcong
+ * @since 24/05/2017
+ */
+public class WordBreak2 {
+
+ public List wordBreakBruteForce(String s, List wordDict) {
+ Set wordSet = new HashSet<>();
+ for (String word : wordDict) {
+ wordSet.add(word);
+ }
+ List wordBreakList = new LinkedList<>();
+ breakWord(s, wordSet, 0, "", wordBreakList);
+ return wordBreakList;
+ }
+
+ public List wordBreakDp(String s, List wordDict) {
+ Set wordSet = new HashSet<>();
+ int maxLength = 0;
+ for (String word : wordDict) {
+ wordSet.add(word);
+ if (word.length() > maxLength) {
+ maxLength = word.length();
+ }
+ }
+ List> breakWordList = new ArrayList<>(s.length());
+ List firstChar = new LinkedList<>();
+ breakWordList.add(firstChar);
+
+ Map> map = new HashMap<>();
+ if (wordSet.contains(s.substring(0, 1))) {
+ firstChar.add(s.substring(0, 1));
+ }
+ map.put(s.substring(0, 1),firstChar);
+ for (int index = 1; index < s.length(); index++) {
+ List currentList = new ArrayList<>();
+ for (int last = index; last >= 0 && (index - last) < maxLength; last--) {
+ String tempString = s.substring(last, index + 1);
+ if (wordSet.contains(tempString)) {
+ if (last == 0) {
+ currentList.add(tempString);
+ } else {
+ List lastBreakList = breakWordList.get(last - 1);
+ for (String lastBreak : lastBreakList) {
+ currentList.add(lastBreak + " " + tempString);
+ }
+ }
+ }
+ }
+ breakWordList.add(currentList);
+ }
+ return breakWordList.get(s.length() - 1);
+ }
+
+ private void breakWord(String s, Set wordSet, int index, String currentWord, List