diff --git a/README.md b/README.md index 8d6bb47..916e80b 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,6 @@ ## learn-java example of learn java +algorithm has moved to [learn-algorithm](https://github.com/wcong/learn-algorithm) + diff --git a/annotation/pom.xml b/annotation/pom.xml new file mode 100644 index 0000000..5c37959 --- /dev/null +++ b/annotation/pom.xml @@ -0,0 +1,46 @@ + + 4.0.0 + + org.wcong + learn-java-annotation + 1.0-SNAPSHOT + jar + + learn-java-annotation + http://maven.apache.org + + + + com.squareup + javapoet + 1.7.0 + + + com.google.auto + auto-common + 0.8 + + + javax.inject + javax.inject + 1 + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 2.3.2 + + 1.7 + 1.7 + UTF-8 + -proc:none + + + + + \ No newline at end of file diff --git a/annotation/src/main/java/org/wcong/test/autovalue/MyAutoValue.java b/annotation/src/main/java/org/wcong/test/autovalue/MyAutoValue.java new file mode 100644 index 0000000..fd90751 --- /dev/null +++ b/annotation/src/main/java/org/wcong/test/autovalue/MyAutoValue.java @@ -0,0 +1,15 @@ +package org.wcong.test.autovalue; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * my auto value + * Created by wcong on 2016/11/25. + */ +@Retention(RetentionPolicy.SOURCE) +@Target(ElementType.TYPE) +public @interface MyAutoValue { +} diff --git a/annotation/src/main/java/org/wcong/test/autovalue/MyAutoValueProcessor.java b/annotation/src/main/java/org/wcong/test/autovalue/MyAutoValueProcessor.java new file mode 100644 index 0000000..9dfccd8 --- /dev/null +++ b/annotation/src/main/java/org/wcong/test/autovalue/MyAutoValueProcessor.java @@ -0,0 +1,184 @@ +package org.wcong.test.autovalue; + +import com.squareup.javapoet.AnnotationSpec; +import com.squareup.javapoet.CodeBlock; +import com.squareup.javapoet.FieldSpec; +import com.squareup.javapoet.JavaFile; +import com.squareup.javapoet.MethodSpec; +import com.squareup.javapoet.ParameterSpec; +import com.squareup.javapoet.TypeName; +import com.squareup.javapoet.TypeSpec; + +import javax.annotation.Generated; +import javax.annotation.processing.AbstractProcessor; +import javax.annotation.processing.RoundEnvironment; +import javax.lang.model.SourceVersion; +import javax.lang.model.element.Element; +import javax.lang.model.element.Modifier; +import javax.lang.model.element.PackageElement; +import javax.lang.model.element.TypeElement; +import javax.lang.model.element.VariableElement; +import javax.lang.model.util.ElementFilter; +import javax.tools.Diagnostic; +import javax.tools.JavaFileObject; +import java.io.IOException; +import java.io.Writer; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +/** + * process for MyAutoValue + * Created by wcong on 2016/11/25. + */ +public class MyAutoValueProcessor extends AbstractProcessor { + + @Override + public SourceVersion getSupportedSourceVersion() { + return SourceVersion.latestSupported(); + } + + @Override + public Set getSupportedAnnotationTypes() { + Set annotationTypes = new HashSet<>(); + annotationTypes.add(MyAutoValue.class.getName()); + return annotationTypes; + } + + @Override + public boolean process(Set annotations, RoundEnvironment roundEnv) { + Set elements = roundEnv.getElementsAnnotatedWith(MyAutoValue.class); + if (elements == null || elements.isEmpty()) { + return true; + } + for (Element element : elements) { + if (!(element instanceof TypeElement)) { + continue; + } + try { + processType(element); + } catch (Exception e) { + processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, e.getMessage(), element); + } + } + return true; + } + + private void processType(Element element) { + TypeElement typeElement = (TypeElement) element; + String className = element.getSimpleName() + "_MyAutoValue"; + TypeSpec.Builder typeSpecBuilder = TypeSpec.classBuilder(className); + typeSpecBuilder.addAnnotation(makeAnnotationSpec()); + typeSpecBuilder.addModifiers(Modifier.PUBLIC); + String packageName = getPackageName(typeElement); + try { + makeFieldAndMethod(typeElement, typeSpecBuilder); + } catch (ClassNotFoundException e) { + processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, e.getMessage()); + } + JavaFile.Builder javaFileBuilder = JavaFile.builder(packageName, typeSpecBuilder.build()); + String text = javaFileBuilder.build().toString(); + try { + JavaFileObject sourceFile = processingEnv.getFiler().createSourceFile(className, element); + Writer writer = sourceFile.openWriter(); + try { + writer.write(text); + } finally { + writer.close(); + } + } catch (IOException e) { + processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, e.getMessage()); + } + } + + private String getPackageName(Element typeElement) { + while (true) { + Element enclosingElement = typeElement.getEnclosingElement(); + if (enclosingElement instanceof PackageElement) { + return ((PackageElement) enclosingElement).getQualifiedName().toString(); + } + typeElement = enclosingElement; + } + } + + private void makeFieldAndMethod(Element element, TypeSpec.Builder typeSpecBuilder) throws ClassNotFoundException { + List elementList = ElementFilter.fieldsIn(element.getEnclosedElements()); + if (elementList == null || elementList.isEmpty()) { + return; + } + List fieldList = new ArrayList<>(elementList.size()); + for (VariableElement variableElement : elementList) { + String fieldName = variableElement.getSimpleName().toString(); + fieldList.add(fieldName); + TypeName typeName = TypeName.get(variableElement.asType()); + typeSpecBuilder.addField(makeFieldSpec(fieldName, typeName)); + typeSpecBuilder.addMethod(makeSetMethod(fieldName, typeName)); + typeSpecBuilder.addMethod(makeGetMethod(fieldName, typeName)); + } + typeSpecBuilder.addMethod(makeToStringMethod(fieldList)); + } + + private MethodSpec makeToStringMethod(List fieldList) { + MethodSpec.Builder toStringMethodSpecBuilder = MethodSpec.methodBuilder("toString"); + toStringMethodSpecBuilder.addModifiers(Modifier.PUBLIC); + toStringMethodSpecBuilder.returns(TypeName.get(String.class)); + CodeBlock.Builder codeBuilder = CodeBlock.builder(); + if (fieldList != null && !fieldList.isEmpty()) { + StringBuilder toStringBuilder = new StringBuilder(fieldList.size() * 10); + for (String field : fieldList) { + if (toStringBuilder.length() > 0) { + toStringBuilder.append(","); + } + toStringBuilder.append("\\\"").append(field).append("\\\"") + .append(":\\\"\"+").append(field).append("+\"\\\""); + } + codeBuilder.add("return \"{" + toStringBuilder.toString() + "}\";"); + } else { + codeBuilder.add("return \"{}\";"); + } + toStringMethodSpecBuilder.addCode(codeBuilder.build()); + return toStringMethodSpecBuilder.build(); + } + + private AnnotationSpec makeAnnotationSpec() { + AnnotationSpec.Builder builder = AnnotationSpec.builder(Generated.class); + CodeBlock.Builder codeBlockBuilder = CodeBlock.builder().add("$S", "MyAutoValue"); + builder.addMember("value", codeBlockBuilder.build()); + return builder.build(); + } + + private static FieldSpec makeFieldSpec(String fieldName, TypeName typeName) { + FieldSpec.Builder fileSpecBuilder = FieldSpec.builder(typeName, fieldName, Modifier.PRIVATE); + return fileSpecBuilder.build(); + } + + private MethodSpec makeSetMethod(String fieldName, TypeName typeName) { + String upperFieldName = getUpperString(fieldName); + MethodSpec.Builder setMethodSpecBuilder = MethodSpec.methodBuilder("set" + upperFieldName); + setMethodSpecBuilder.addModifiers(Modifier.PUBLIC); + setMethodSpecBuilder.returns(TypeName.VOID); + ParameterSpec.Builder parameterBuilder = ParameterSpec.builder(typeName, fieldName); + setMethodSpecBuilder.addParameter(parameterBuilder.build()); + setMethodSpecBuilder.addCode(CodeBlock.builder().add("this." + fieldName + " = " + fieldName + ";\n").build()); + return setMethodSpecBuilder.build(); + } + + private String getUpperString(String fieldName) { + if (fieldName.length() == 1) { + fieldName = fieldName.toUpperCase(); + } else { + fieldName = fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1); + } + return fieldName; + } + + private MethodSpec makeGetMethod(String fieldName, TypeName typeName) { + String upperFieldName = getUpperString(fieldName); + MethodSpec.Builder getMethodSpecBuilder = MethodSpec.methodBuilder("get" + upperFieldName); + getMethodSpecBuilder.addModifiers(Modifier.PUBLIC); + getMethodSpecBuilder.returns(typeName); + getMethodSpecBuilder.addCode(CodeBlock.builder().add("return " + fieldName + ";\n").build()); + return getMethodSpecBuilder.build(); + } +} diff --git a/annotation/src/main/java/org/wcong/test/mydagger/MyComponent.java b/annotation/src/main/java/org/wcong/test/mydagger/MyComponent.java new file mode 100644 index 0000000..a31b0bb --- /dev/null +++ b/annotation/src/main/java/org/wcong/test/mydagger/MyComponent.java @@ -0,0 +1,15 @@ +package org.wcong.test.mydagger; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * @author wcong + * @since 2016/12/4 + */ +@Retention(RetentionPolicy.SOURCE) +@Target(ElementType.TYPE) +public @interface MyComponent { +} diff --git a/annotation/src/main/java/org/wcong/test/mydagger/MyComponentProcessor.java b/annotation/src/main/java/org/wcong/test/mydagger/MyComponentProcessor.java new file mode 100644 index 0000000..2db6fdf --- /dev/null +++ b/annotation/src/main/java/org/wcong/test/mydagger/MyComponentProcessor.java @@ -0,0 +1,32 @@ +package org.wcong.test.mydagger; + +import com.google.auto.common.BasicAnnotationProcessor; +import com.squareup.javapoet.ParameterizedTypeName; + +import javax.annotation.processing.Filer; +import javax.annotation.processing.Messager; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * my component processor + * + * @author wcong + * @since 2016/12/4 + */ +public class MyComponentProcessor extends BasicAnnotationProcessor { + + private Map> dependencyMap = new HashMap<>(); + + @Override + protected Iterable initSteps() { + Filer filer = processingEnv.getFiler(); + Messager messager = processingEnv.getMessager(); + List processingStepList = new ArrayList<>(); + processingStepList.add(new MyProvidesStep(filer, messager, dependencyMap)); + processingStepList.add(new MyComponentStep(filer, messager, dependencyMap)); + return processingStepList; + } +} diff --git a/annotation/src/main/java/org/wcong/test/mydagger/MyComponentStep.java b/annotation/src/main/java/org/wcong/test/mydagger/MyComponentStep.java new file mode 100644 index 0000000..661adcd --- /dev/null +++ b/annotation/src/main/java/org/wcong/test/mydagger/MyComponentStep.java @@ -0,0 +1,163 @@ +package org.wcong.test.mydagger; + +import com.google.auto.common.BasicAnnotationProcessor; +import com.google.common.collect.SetMultimap; +import com.squareup.javapoet.ClassName; +import com.squareup.javapoet.JavaFile; +import com.squareup.javapoet.MethodSpec; +import com.squareup.javapoet.ParameterizedTypeName; +import com.squareup.javapoet.TypeName; +import com.squareup.javapoet.TypeSpec; +import org.wcong.test.util.ElementUtils; +import org.wcong.test.util.ListUtils; + +import javax.annotation.processing.Filer; +import javax.annotation.processing.Messager; +import javax.inject.Provider; +import javax.lang.model.element.Element; +import javax.lang.model.element.ExecutableElement; +import javax.lang.model.element.Modifier; +import javax.lang.model.element.TypeElement; +import javax.lang.model.type.TypeMirror; +import javax.lang.model.util.ElementFilter; +import javax.tools.Diagnostic; +import javax.tools.JavaFileObject; +import java.io.IOException; +import java.io.Writer; +import java.lang.annotation.Annotation; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * process step ,do it last. + * export one class,make all provide class + * + * @author wcong + * @since 2016/12/4 + */ +public class MyComponentStep implements BasicAnnotationProcessor.ProcessingStep { + private Filer filer; + + private Messager messager; + + private Map> dependencyMap; + + public MyComponentStep(Filer filer, Messager messager, Map> dependencyMap) { + this.messager = messager; + this.filer = filer; + this.dependencyMap = dependencyMap; + } + + @Override + public Set> annotations() { + Set> classSet = new HashSet<>(); + classSet.add(MyComponent.class); + return classSet; + } + + @Override + public Set process(SetMultimap, Element> elementsByAnnotation) { + Set elementSet = elementsByAnnotation.get(MyComponent.class); + try { + for (Element element : elementSet) { + processComponent(element); + } + } catch (Exception e) { + messager.printMessage(Diagnostic.Kind.ERROR, e.getMessage()); + } + return Collections.emptySet(); + } + + private void processComponent(Element element) { + TypeElement typeElement = (TypeElement) element; + String className = "MyDagger_" + typeElement.getSimpleName().toString(); + TypeSpec.Builder typeSpecBuilder = TypeSpec.classBuilder(className); + typeSpecBuilder.addSuperinterface(TypeName.get(element.asType())); + + List startTypeName = new ArrayList<>(10); + List methodList = ElementFilter.methodsIn(element.getEnclosedElements()); + Map typeParameterizedMap = new HashMap<>(); + for (ExecutableElement executableElement : methodList) { + TypeMirror returnType = executableElement.getReturnType(); + ParameterizedTypeName parameterizedTypeName = ParameterizedTypeName.get(ClassName.get(Provider.class), TypeName.get(returnType)); + typeParameterizedMap.put(returnType, parameterizedTypeName); + startTypeName.add(parameterizedTypeName); + } + Set fieldInitialList = new LinkedHashSet<>(dependencyMap.size()); + for (ParameterizedTypeName parameterizedTypeName : startTypeName) { + ergodicDependency(parameterizedTypeName, fieldInitialList); + } + Map fieldNameMap = generateFieldMap(fieldInitialList); + for (ParameterizedTypeName field : fieldInitialList) { + typeSpecBuilder.addField(field, fieldNameMap.get(field), Modifier.PRIVATE); + } + + fieldsAndConstruct(typeSpecBuilder, fieldInitialList, fieldNameMap); + + implementMethods(typeSpecBuilder, methodList, typeParameterizedMap, fieldNameMap); + + String packageName = ElementUtils.getPackageName(typeElement); + JavaFile.Builder javaFileBuilder = JavaFile.builder(packageName, typeSpecBuilder.build()); + String text = javaFileBuilder.build().toString(); + + ElementUtils.writeFile(filer,messager,className,text,element); + } + + private void fieldsAndConstruct(TypeSpec.Builder typeSpecBuilder, Set fieldInitialList, Map fieldNameMap) { + MethodSpec.Builder constructBuilder = MethodSpec.constructorBuilder(); + for (ParameterizedTypeName field : fieldInitialList) { + String fieldName = fieldNameMap.get(field); + List dependencyList = dependencyMap.get(field); + if (dependencyList == null || dependencyList.isEmpty()) { + constructBuilder.addCode("this." + fieldName + "=" + fieldName + "_MyDagger_Factory.create();\n"); + } else { + List paramList = new ArrayList<>(dependencyList.size()); + for (ParameterizedTypeName parameterizedTypeName : dependencyList) { + paramList.add(fieldNameMap.get(parameterizedTypeName)); + } + constructBuilder.addCode("this." + fieldName + "=" + fieldName + "_MyDagger_Factory.create(" + ListUtils.implode(paramList, ",") + ");\n"); + } + } + typeSpecBuilder.addMethod(constructBuilder.build()); + } + + private void implementMethods(TypeSpec.Builder typeSpecBuilder, List methodList, Map typeParameterizedMap, Map fieldNameMap) { + for (ExecutableElement method : methodList) { + MethodSpec.Builder methodBuilder = MethodSpec.methodBuilder(method.getSimpleName().toString()); + methodBuilder.returns(TypeName.get(method.getReturnType())); + methodBuilder.addModifiers(Modifier.PUBLIC); + methodBuilder.addCode("return " + fieldNameMap.get(typeParameterizedMap.get(method.getReturnType())) + ".get();\n"); + typeSpecBuilder.addMethod(methodBuilder.build()); + } + } + + private Map generateFieldMap(Set fieldInitialList) { + Map fieldNameMap = new HashMap<>(); + for (ParameterizedTypeName field : fieldInitialList) { + String firstClass = field.typeArguments.get(0).toString(); + String[] fieldNameArray = firstClass.split("\\."); + String fieldName = fieldNameArray[fieldNameArray.length - 1]; + fieldNameMap.put(field, fieldName); + } + return fieldNameMap; + } + + private void ergodicDependency(ParameterizedTypeName parameterizedTypeName, Set fieldInitialList) { + List dependencyList = dependencyMap.get(parameterizedTypeName); + if (dependencyList != null && !dependencyList.isEmpty()) { + for (ParameterizedTypeName innerParameterizedTypeName : dependencyList) { + if (fieldInitialList.contains(innerParameterizedTypeName)) { + continue; + } + ergodicDependency(innerParameterizedTypeName, fieldInitialList); + } + } + fieldInitialList.add(parameterizedTypeName); + } +} diff --git a/annotation/src/main/java/org/wcong/test/mydagger/MyInject.java b/annotation/src/main/java/org/wcong/test/mydagger/MyInject.java new file mode 100644 index 0000000..0f52dad --- /dev/null +++ b/annotation/src/main/java/org/wcong/test/mydagger/MyInject.java @@ -0,0 +1,8 @@ +package org.wcong.test.mydagger; + +/** + * @author wcong + * @since 2016/12/4 + */ +public class MyInject { +} diff --git a/annotation/src/main/java/org/wcong/test/mydagger/MyProvides.java b/annotation/src/main/java/org/wcong/test/mydagger/MyProvides.java new file mode 100644 index 0000000..7d29e78 --- /dev/null +++ b/annotation/src/main/java/org/wcong/test/mydagger/MyProvides.java @@ -0,0 +1,17 @@ +package org.wcong.test.mydagger; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * my provides + * + * @author wcong + * @since 2016/12/4 + */ +@Retention(RetentionPolicy.SOURCE) +@Target({ ElementType.METHOD, ElementType.TYPE }) +public @interface MyProvides { +} diff --git a/annotation/src/main/java/org/wcong/test/mydagger/MyProvidesStep.java b/annotation/src/main/java/org/wcong/test/mydagger/MyProvidesStep.java new file mode 100644 index 0000000..8bb21ee --- /dev/null +++ b/annotation/src/main/java/org/wcong/test/mydagger/MyProvidesStep.java @@ -0,0 +1,192 @@ +package org.wcong.test.mydagger; + +import com.google.auto.common.BasicAnnotationProcessor; +import com.google.common.collect.SetMultimap; +import com.squareup.javapoet.ClassName; +import com.squareup.javapoet.JavaFile; +import com.squareup.javapoet.MethodSpec; +import com.squareup.javapoet.ParameterizedTypeName; +import com.squareup.javapoet.TypeName; +import com.squareup.javapoet.TypeSpec; +import org.wcong.test.util.ElementUtils; +import org.wcong.test.util.ListUtils; + +import javax.annotation.processing.Filer; +import javax.annotation.processing.Messager; +import javax.inject.Inject; +import javax.inject.Provider; +import javax.lang.model.element.Element; +import javax.lang.model.element.ExecutableElement; +import javax.lang.model.element.Modifier; +import javax.lang.model.element.PackageElement; +import javax.lang.model.element.TypeElement; +import javax.lang.model.element.VariableElement; +import javax.lang.model.type.TypeMirror; +import javax.tools.Diagnostic; +import javax.tools.JavaFileObject; +import java.io.IOException; +import java.io.Writer; +import java.lang.annotation.Annotation; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * @author wcong + * @since 2016/12/4 + */ +public class MyProvidesStep implements BasicAnnotationProcessor.ProcessingStep { + + private Filer filer; + + private Messager messager; + + private Map> dependencyMap; + + public MyProvidesStep(Filer filer, Messager messager,Map> dependencyMap) { + this.messager = messager; + this.filer = filer; + this.dependencyMap = dependencyMap; + } + + @Override + public Set> annotations() { + Set> classSet = new HashSet<>(); + classSet.add(MyProvides.class); + return classSet; + } + + @Override + public Set process(SetMultimap, Element> elementsByAnnotation) { + Set provideElements = elementsByAnnotation.get(MyProvides.class); + if (provideElements == null || provideElements.isEmpty()) { + return Collections.emptySet(); + } + for (Element element : provideElements) { + processProvideElement(element); + } + return Collections.emptySet(); + } + + private void processProvideElement(Element element) { + TypeElement typeElement = (TypeElement) element; + + String className = element.getSimpleName() + "_MyDagger_Factory"; + ParameterizedTypeName superClass = ParameterizedTypeName.get(ClassName.get(Provider.class), TypeName.get(element.asType())); + TypeSpec.Builder typeSpecBuilder = TypeSpec.classBuilder(className); + typeSpecBuilder.addSuperinterface(superClass); + typeSpecBuilder.addModifiers(Modifier.PUBLIC); + + List injectParams = getInjectConstructMethod(typeElement); + Map typeNameMap = makeProvideParams(injectParams); + if( !typeNameMap.isEmpty() ){ + List dependencyList = new ArrayList<>(typeNameMap.size()); + for( Map.Entry typeNameEntry : typeNameMap.entrySet() ){ + dependencyList.add(typeNameEntry.getValue()); + typeSpecBuilder.addField(typeNameEntry.getValue(),typeNameEntry.getKey(),Modifier.PRIVATE,Modifier.FINAL); + } + dependencyMap.put(superClass,dependencyList); + typeSpecBuilder.addMethod(makeContructMethod(typeNameMap)); + } + typeSpecBuilder.addMethod(makeGetMethod(typeElement,typeNameMap)); + typeSpecBuilder.addMethod(makeCreateMethod(className, superClass,typeNameMap)); + + String packageName = ElementUtils.getPackageName(typeElement); + JavaFile.Builder javaFileBuilder = JavaFile.builder(packageName, typeSpecBuilder.build()); + String text = javaFileBuilder.build().toString(); + + ElementUtils.writeFile(filer,messager,className,text,element); + } + + private MethodSpec makeContructMethod(Map typeNameMap){ + MethodSpec.Builder contructMethod = MethodSpec.constructorBuilder(); + for( Map.Entry typeNameEntry : typeNameMap.entrySet() ){ + contructMethod.addParameter(typeNameEntry.getValue(),typeNameEntry.getKey()); + contructMethod.addCode("this."+typeNameEntry.getKey()+"="+typeNameEntry.getKey()+";\n"); + } + return contructMethod.build(); + } + + private Map makeProvideParams(List injectParams){ + if( injectParams.isEmpty() ){ + return Collections.emptyMap(); + } + Map map = new HashMap<>(); + for(TypeMirror typeMirror : injectParams){ + String[] splitArray = typeMirror.toString().split("\\."); + map.put(splitArray[splitArray.length-1],ParameterizedTypeName.get(ClassName.get(Provider.class),TypeName.get(typeMirror))); + } + return map; + } + + private List getInjectConstructMethod(TypeElement typeElement){ + for(Element element : typeElement.getEnclosedElements() ){ + if( ! (element instanceof ExecutableElement)){ + continue; + } + ExecutableElement executableElement = (ExecutableElement) element; + if( !"".equals(executableElement.getSimpleName().toString()) ){ + continue; + } + Inject inject = executableElement.getAnnotation(Inject.class); + if( inject == null ){ + continue; + } + List variableElementList = executableElement.getParameters(); + if( !variableElementList.isEmpty() ){ + List typeMirrors = new ArrayList<>(variableElementList.size()); + for( VariableElement variableElement : variableElementList ){ + typeMirrors.add(variableElement.asType()); + } + return typeMirrors; + } + } + return Collections.emptyList(); + } + + private MethodSpec makeGetMethod(TypeElement typeElement,Map typeNameMap ) { + MethodSpec.Builder getMethodSpecBuilder = MethodSpec.methodBuilder("get"); + getMethodSpecBuilder.returns(TypeName.get(typeElement.asType())); + getMethodSpecBuilder.addModifiers(Modifier.PUBLIC); + if( typeNameMap.isEmpty() ) { + getMethodSpecBuilder.addCode("return new " + typeElement.getSimpleName() + "();\n"); + }else{ + StringBuilder construct = new StringBuilder(); + construct.append("return new ").append( typeElement.getSimpleName()).append("("); + List paramList = new ArrayList<>(typeNameMap.size()); + for( Map.Entry typeNameEntry :typeNameMap.entrySet()){ + paramList.add(typeNameEntry.getKey()+".get()"); + } + construct.append(ListUtils.implode(paramList,",")).append(");\n"); + getMethodSpecBuilder.addCode(construct.toString()); + } + return getMethodSpecBuilder.build(); + } + + private MethodSpec makeCreateMethod(String className, ParameterizedTypeName superClass,Map typeNameMap ) { + MethodSpec.Builder createMethodSpecBuilder = MethodSpec.methodBuilder("create"); + createMethodSpecBuilder.returns(superClass); + if( !typeNameMap.isEmpty() ){ + for( Map.Entry typeNameEntry : typeNameMap.entrySet() ) { + createMethodSpecBuilder.addParameter(typeNameEntry.getValue(),typeNameEntry.getKey()); + } + } + createMethodSpecBuilder.addModifiers(Modifier.PUBLIC, Modifier.STATIC); + if( typeNameMap.isEmpty() ) { + createMethodSpecBuilder.addCode("return new " + className + "();\n"); + }else{ + createMethodSpecBuilder.addCode("return new "+className+"("); + List paramList = new ArrayList<>(typeNameMap.size()); + for( Map.Entry typeNameEntry:typeNameMap.entrySet() ){ + paramList.add(typeNameEntry.getKey()); + } + createMethodSpecBuilder.addCode(ListUtils.implode(paramList,",")+");\n"); + } + return createMethodSpecBuilder.build(); + } + +} diff --git a/annotation/src/main/java/org/wcong/test/util/ElementUtils.java b/annotation/src/main/java/org/wcong/test/util/ElementUtils.java new file mode 100644 index 0000000..eaf9f92 --- /dev/null +++ b/annotation/src/main/java/org/wcong/test/util/ElementUtils.java @@ -0,0 +1,39 @@ +package org.wcong.test.util; + +import javax.annotation.processing.Filer; +import javax.annotation.processing.Messager; +import javax.lang.model.element.Element; +import javax.lang.model.element.PackageElement; +import javax.tools.Diagnostic; +import javax.tools.JavaFileObject; +import java.io.IOException; +import java.io.Writer; + +/** + * Created by wcong on 2016/12/6. + */ +public class ElementUtils { + public static String getPackageName(Element element) { + while (true) { + Element enclosingElement = element.getEnclosingElement(); + if (enclosingElement instanceof PackageElement) { + return ((PackageElement) enclosingElement).getQualifiedName().toString(); + } + element = enclosingElement; + } + } + + public static void writeFile(Filer filer, Messager messager, String className, String text, Element element) { + try { + JavaFileObject sourceFile = filer.createSourceFile(className, element); + Writer writer = sourceFile.openWriter(); + try { + writer.write(text); + } finally { + writer.close(); + } + } catch (IOException e) { + messager.printMessage(Diagnostic.Kind.ERROR, e.getMessage()); + } + } +} diff --git a/annotation/src/main/java/org/wcong/test/util/ListUtils.java b/annotation/src/main/java/org/wcong/test/util/ListUtils.java new file mode 100644 index 0000000..b5c2708 --- /dev/null +++ b/annotation/src/main/java/org/wcong/test/util/ListUtils.java @@ -0,0 +1,24 @@ +package org.wcong.test.util; + +import java.util.Iterator; +import java.util.List; + +/** + * Created by wcong on 2016/12/6. + */ +public class ListUtils { + + public static String implode(List list, String joint) { + if (list == null || list.isEmpty()) { + return ""; + } + Iterator iterator = list.iterator(); + StringBuilder sb = new StringBuilder(); + sb.append(iterator.next()); + while (iterator.hasNext()) { + sb.append(joint).append(iterator.next()); + } + return sb.toString(); + } + +} diff --git a/annotation/src/main/resources/META-INF/services/javax.annotation.processing.Processor b/annotation/src/main/resources/META-INF/services/javax.annotation.processing.Processor new file mode 100644 index 0000000..8783c37 --- /dev/null +++ b/annotation/src/main/resources/META-INF/services/javax.annotation.processing.Processor @@ -0,0 +1,2 @@ +org.wcong.test.autovalue.MyAutoValueProcessor +org.wcong.test.mydagger.MyComponentProcessor \ No newline at end of file diff --git a/doc/dagger/AutoValue.md b/doc/dagger/AutoValue.md new file mode 100644 index 0000000..fd38dcd --- /dev/null +++ b/doc/dagger/AutoValue.md @@ -0,0 +1,196 @@ +### 前言 +[上一篇文章](./76e9e3a8ec0f)介绍了JavaPoet的使用,这里在介绍一下[AutoValue](https://github.com/google/auto)的原理,并模仿自定义实现一个AutoValue。 +AutoValue的是Google为了实现*ValueClass*设计的自动编译框架,具体的介绍可以参考Google的官方[说明](https://github.com/google/auto/blob/master/value/userguide/index.md)。 +Dagger内部也大量使用了AutoValue的功能,来实现*ValueClass*。 +### AutoValue +AutoValue嵌入到JavaClass的编译过程,读取被注解的类,来创建一个新的ValueClass。这里有一个完整使用的[例子](https://github.com/wcong/learn-java/blob/master/src/main/java/org/wcong/test/autovalue/AutoValueTest.java)。 +这里主要介绍一下AutoValue的实现。 +1. 定义注解*AutoValue*。 +``` + @Retention(RetentionPolicy.SOURCE) + @Target(ElementType.TYPE) + public @interface AutoValue { + } +``` +2. 注册*processor*,AutoValue的jar包中的*META-INF/services*路径里面包含文件*javax.annotation.processing.Processor*,文件里包含了注册的*processor*,换行分割。这里面注册了*AutoValueProcessor*。 +3. *AutoValueProcessor*的*process*方法实现了主要的处理逻辑,读取注释的类的信息,构造新的类,并写入文件。*processType*方法是处理单个类的方法,主要的逻辑如下 +``` + AutoValueTemplateVars vars = new AutoValueTemplateVars(); + vars.pkg = TypeSimplifier.packageNameOf(type); + vars.origClass = TypeSimplifier.classNameOf(type); + vars.simpleClassName = TypeSimplifier.simpleNameOf(vars.origClass); + vars.subclass = TypeSimplifier.simpleNameOf(subclass); + vars.finalSubclass = TypeSimplifier.simpleNameOf(finalSubclass); + vars.isFinal = applicableExtensions.isEmpty(); + vars.types = processingEnv.getTypeUtils(); + determineObjectMethodsToGenerate(methods, vars); + defineVarsForType(type, vars, toBuilderMethods, propertyMethods, builder); + GwtCompatibility gwtCompatibility = new GwtCompatibility(type); + vars.gwtCompatibleAnnotation = gwtCompatibility.gwtCompatibleAnnotationString(); + String text = vars.toText(); + text = Reformatter.fixup(text); + writeSourceFile(subclass, text, type); +``` +*AutoValueTemplateVars*保存了新的类的信息,并根据对应的模板生成源文件字符串. +``` + private void writeSourceFile(String className, String text, TypeElement originatingType) { + try { + JavaFileObject sourceFile = + processingEnv.getFiler().createSourceFile(className, originatingType); + Writer writer = sourceFile.openWriter(); + try { + writer.write(text); + } finally { + writer.close(); + } + } catch (IOException e) { + processingEnv.getMessager().printMessage(Diagnostic.Kind.WARNING, + "Could not write generated class " + className + ": " + e); + } + } +``` +*writeSourceFile*则会根据原生api将源代码写入本地文件。 + +### MyAutoValue +所以自定义*AutoValue*也是类似的原理。这里构造*MyAutoValue*来读取注解的类,生成新的带有get,set和toString方法类。 +因为*processor*的注册只能在jar中使用,不能跟源文件放在一起,所以这里新建了一个[工程](https://github.com/wcong/learn-java/tree/master/annotation)来实现*MyAutoValue*,使用方法在[这里](https://github.com/wcong/learn-java/blob/master/src/main/java/org/wcong/test/autovalue/MyAutoValueTest.java)。 +1. 定义*MyAutoValue*。 +``` +@Retention(RetentionPolicy.SOURCE) +@Target(ElementType.TYPE) +public @interface MyAutoValue { +} +``` +2. *MyAutoValueProcessor*。同样先在*resources/META-INF/services*下新建*javax.annotation.processing.Processor*,并注册*MyAutoValueProcessor*。 +*MyAutoValueProcessor*继承了*AbstractProcessor*,并在*process*中实现了主要的逻辑。 +``` + @Override + public boolean process(Set annotations, RoundEnvironment roundEnv) { + Set elements = roundEnv.getElementsAnnotatedWith(MyAutoValue.class); + if (elements == null || elements.isEmpty()) { + return true; + } + for (Element element : elements) { + if (!(element instanceof TypeElement)) { + continue; + } + try { + processType(element); + } catch (Exception e) { + processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, e.getMessage(), element); + } + } + return true; + } +``` +这里去取了所有被*MyAutoValue*注释的类,并交给processType去处理。 +``` + private void processType(Element element) { + TypeElement typeElement = (TypeElement) element; + String className = element.getSimpleName() + "_MyAutoValue"; + TypeSpec.Builder typeSpecBuilder = TypeSpec.classBuilder(className); + typeSpecBuilder.addAnnotation(makeAnnotationSpec()); + typeSpecBuilder.addModifiers(Modifier.PUBLIC); + String packageName = getPackageName(typeElement); + try { + makeFieldAndMethod(typeElement, typeSpecBuilder); + } catch (ClassNotFoundException e) { + processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, e.getMessage()); + } + JavaFile.Builder javaFileBuilder = JavaFile.builder(packageName, typeSpecBuilder.build()); + String text = javaFileBuilder.build().toString(); + try { + JavaFileObject sourceFile = processingEnv.getFiler().createSourceFile(className, element); + Writer writer = sourceFile.openWriter(); + try { + writer.write(text); + } finally { + writer.close(); + } + } catch (IOException e) { + processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, e.getMessage()); + } + } +``` +*processType*会读取类的字段生成一个新的*_MyAutoValue的类,并根据原有类的字段生成get,set和toString方法,然后将新类写入到本地文件中。 +``` + private void makeFieldAndMethod(Element element, TypeSpec.Builder typeSpecBuilder) throws ClassNotFoundException { + List elementList = ElementFilter.fieldsIn(element.getEnclosedElements()); + if (elementList == null || elementList.isEmpty()) { + return; + } + List fieldList = new ArrayList<>(elementList.size()); + for (VariableElement variableElement : elementList) { + String fieldName = variableElement.getSimpleName().toString(); + fieldList.add(fieldName); + TypeName typeName = TypeName.get(variableElement.asType()); + typeSpecBuilder.addField(makeFieldSpec(fieldName, typeName)); + typeSpecBuilder.addMethod(makeSetMethod(fieldName, typeName)); + typeSpecBuilder.addMethod(makeGetMethod(fieldName, typeName)); + } + typeSpecBuilder.addMethod(makeToStringMethod(fieldList)); + } +``` +*makeFieldAndMethod*就是具体的构造字段和方法的逻辑,内部使用JavaPoet实现的,可以参考完整代码和上一篇文章,这里就不列出了。 +3. 打包编译,需要注意的*META-INF/services*的*javax.annotation.processing.Processor*会阻止javac的编译,打完包会发现里面没有class文件,所以需要加上特殊的参数。 +``` + + + + org.apache.maven.plugins + maven-compiler-plugin + 2.3.2 + + 1.7 + 1.7 + UTF-8 + -proc:none + + + + +``` +加上*-proc:none*就可以实现完整的打包了。 +4. 使用*MyAutoValue*。在*MyAutoValueClassTest*类上注解*MyAutoValue*。 +``` + @MyAutoValue + public class MyAutoValueClassTest { + private String a; + private String b; + private int c; + } +``` +编译完后就会生成以下的新类,会发现自定带上了get,set和toString的方法。 +``` +public class MyAutoValueClassTest_MyAutoValue { + private String a; + private String b; + private int c; + public MyAutoValueClassTest_MyAutoValue() { + } + public void setA(String a) { + this.a = a; + } + public String getA() { + return this.a; + } + public void setB(String b) { + this.b = b; + } + public String getB() { + return this.b; + } + public void setC(int c) { + this.c = c; + } + public int getC() { + return this.c; + } + public String toString() { + return "{\"a\":\"" + this.a + "\",\"b\":\"" + this.b + "\",\"c\":\"" + this.c + "\"}"; + } +} +``` + +### 结语 +dagger的实现跟AutoValue类似,也是根据注解嵌入编译实现新的类,只是AutoValue的逻辑比较简单,只是实现ValueClass的构造,dagger会涉及到更多依赖注入的功能。后面会介绍更多dagger的内容。 \ No newline at end of file diff --git a/doc/dagger/JavaPoet.md b/doc/dagger/JavaPoet.md new file mode 100644 index 0000000..e7ebd8e --- /dev/null +++ b/doc/dagger/JavaPoet.md @@ -0,0 +1,101 @@ +### 前言 +最近在用[dagger](https://github.com/google/dagger)开发应用,dagger是google在[square](https://github.com/square/dagger)的基础上去反射的依赖注入框架。 +dagger会根据定义的注解在编译阶段自动生成依赖注入的代码,来减少运行期间反射的开销。 +dagger依赖了JavaPoet和JavaFormat来实现编译代码,这里主要介绍下JavaPoet的内容和使用。 + +### JavaPoet +JavaPoet这样定义自己的项目。 +``` +Use beautiful Java code to generate beautiful Java code +``` +所以JavaPoet定义了一系列类来尽可能优雅的描述java源文件的结构。观察JavaPoet的代码主要的接口可以分为以下几种: + +* Spec 用来描述Java中基本的元素,包括类型,注解,字段,方法和参数 + * AnnotationSpec + * FieldSpec + * MethodSpec + * ParameterSpec + * TypeSpec +* Name 用来描述类型的引用,包括Void,和元素类型(int,long等) + * TypeName + * ArrayTypeName + * ClassName + * ParameterizedTypeName + * TypeVariableName + * WildcardTypeName +* CodeBlock 用来描述代码块的内容,包括普通的赋值,if判断,循环判断等 +* JavaFile 完整的Java文件 +* CodeWriter 读取JavaFile并转换成Java源文件 + +### 使用样例 +通过下面的maven定义可以引用JavaPoet包。 +``` + + com.squareup + javapoet + 1.7.0 + +``` +这里使用JavaPoet定义了一个简单的Java类,完整的代码放在[Github](https://github.com/wcong/learn-java/blob/master/src/main/java/org/wcong/test/poet/JavaFileTest.java)。 +这里介绍一下主要的类。 +1. AnnotationSpec 添加*MyAnnotation*的注解,然后设置属性*hello=world*。 +``` + private static AnnotationSpec makeAnnotationSpec() { + AnnotationSpec.Builder builder = AnnotationSpec.builder(ClassName.get("org.wcong.test.poet", "MyAnnotation")); + CodeBlock.Builder codeBlockBuilder = CodeBlock.builder().add("$S", "world"); + builder.addMember("hello", codeBlockBuilder.build()); + return builder.build(); + } +``` +2. FieldSpec 创建*hello*的字段并初始化为“world”。 +``` + private static FieldSpec makeFieldSpec() { + FieldSpec.Builder fileSpecBuilder = FieldSpec.builder(String.class, "hello", Modifier.PRIVATE); + fileSpecBuilder.initializer(CodeBlock.of("\"world\"")); + return fileSpecBuilder.build(); + } +``` +3. MethodSpec 创建*getHello*,*setHello*,*toString*方法。 +*toString*使用了*ControlFlow*判断了*hello*不等于null,返回"hello world",等于null的时候返回空。 +``` + private static MethodSpec makeToStringMethod() { + MethodSpec.Builder toStringBuilder = MethodSpec.methodBuilder("toString"); + toStringBuilder.addModifiers(Modifier.PUBLIC); + toStringBuilder.returns(TypeName.get(String.class)); + CodeBlock.Builder toStringCodeBuilder = CodeBlock.builder(); + toStringCodeBuilder.beginControlFlow("if( hello != null )"); + toStringCodeBuilder.add(CodeBlock.of("return \"hello \"+hello;")); + toStringCodeBuilder.endControlFlow(); + toStringBuilder.addCode(toStringCodeBuilder.build()); + return toStringBuilder.build(); + } + private static MethodSpec makeSetMethod() { + MethodSpec.Builder setMethodSpecBuilder = MethodSpec.methodBuilder("setHello"); + setMethodSpecBuilder.addModifiers(Modifier.PUBLIC); + setMethodSpecBuilder.returns(TypeName.VOID); + ParameterSpec.Builder parameterBuilder = ParameterSpec.builder(TypeName.get(String.class), "hello"); + setMethodSpecBuilder.addParameter(parameterBuilder.build()); + setMethodSpecBuilder.addCode(CodeBlock.builder().add("this.hello = hello;").build()); + return setMethodSpecBuilder.build(); + } + private static MethodSpec makeGetMethod() { + MethodSpec.Builder getMethodSpecBuilder = MethodSpec.methodBuilder("getHello"); + getMethodSpecBuilder.addModifiers(Modifier.PUBLIC); + getMethodSpecBuilder.returns(TypeName.get(String.class)); + getMethodSpecBuilder.addCode(CodeBlock.builder().add("return hello;").build()); + return getMethodSpecBuilder.build(); + } +``` +4. JavaFile JavaPoet的主入口,用来描述Java源文件。 +``` + public static void main(String[] args) { + TypeSpec.Builder typeSpecBuilder = TypeSpec.classBuilder("JavaFile"); + typeSpecBuilder.addAnnotation(makeAnnotationSpec()); + typeSpecBuilder.addField(makeFieldSpec()); + typeSpecBuilder.addMethods(makeMethodSpec()); + JavaFile.Builder javaFileBuilder = JavaFile.builder("org.wcong.test.poet", typeSpecBuilder.build()); + System.out.println(javaFileBuilder.build().toString()); + } +``` +### 结语 +dagger使用JavaPoet来保存自动生成的类的信息,并通过[JavaFormat](https://github.com/google/google-java-format)来格式化生成的Java源文件。后面会介绍关于JavaFormat的内容。 diff --git a/doc/dagger/MyDagger.md b/doc/dagger/MyDagger.md new file mode 100644 index 0000000..06d57ef --- /dev/null +++ b/doc/dagger/MyDagger.md @@ -0,0 +1 @@ +### 前言 \ No newline at end of file diff --git a/pom.xml b/pom.xml index 5807811..5f4edf1 100644 --- a/pom.xml +++ b/pom.xml @@ -3,11 +3,11 @@ 4.0.0 org.wcong - learn-spring + learn-java 1.0-SNAPSHOT jar - learn-spring + learn-java http://maven.apache.org @@ -22,7 +22,7 @@ junit junit - 3.8.1 + 4.13.1 test @@ -206,6 +206,11 @@ jackson-annotations 2.3.3 + + io.reactivex.rxjava2 + rxjava + 2.1.6 + org.freemarker freemarker @@ -218,34 +223,34 @@ - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + @@ -259,5 +264,85 @@ 4.0.33.Final + + com.google.inject + guice + 4.1.0 + + + + com.google.inject.extensions + guice-servlet + 4.1.0 + + + com.google.inject.extensions + guice-multibindings + 4.1.0 + + + + com.google.dagger + dagger + 2.7 + + + com.google.dagger + dagger-compiler + 2.7 + true + + + com.google.auto + auto-common + 0.8 + + + com.google.auto.service + auto-service + 1.0-rc2 + + + com.google.auto.value + auto-value + 1.3 + + + com.squareup + javapoet + 1.7.0 + + + com.google.googlejavaformat + google-java-format + 1.0 + + + org.eclipse.jdt + org.eclipse.jdt.core + 3.10.0 + + + org.wcong + learn-java-annotation + 1.0-SNAPSHOT + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 2.3.2 + + 1.7 + 1.7 + UTF-8 + false + false + + + + diff --git a/src/main/java/org/wcong/App.java b/src/main/java/org/wcong/App.java index 68e5218..da1598c 100644 --- a/src/main/java/org/wcong/App.java +++ b/src/main/java/org/wcong/App.java @@ -1,252 +1,398 @@ package org.wcong; -import java.lang.reflect.ParameterizedType; -import java.math.BigDecimal; -import java.util.Arrays; +import org.wcong.test.hackerrank.string.PerfectString; + +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; +import java.util.Scanner; /** * Hello world! */ public class App { - static int a; - - public static void main(String[] args) { - System.out.println(a); - } - - public static Class findSuperClassParameterType(Object instance, int parameterIndex) { - Class subClass = instance.getClass(); - while (subClass != subClass.getSuperclass()) { - // instance.getClass() is no subclass of classOfInterest or instance is a direct instance of classOfInterest - subClass = subClass.getSuperclass(); - if (subClass == null) throw new IllegalArgumentException(); - } - ParameterizedType parameterizedType = (ParameterizedType) subClass.getGenericSuperclass(); - return (Class) parameterizedType.getActualTypeArguments()[parameterIndex]; - } - - public class A { - } - - public static class B { - } - - - public enum LogisticsCompanyEnum { - - QITA("Q", 0, "其它"), SHUNFENG("S", 1, "顺丰速运"), ZHONGTONG("Z", 2, "中通快递"), SHENTONG("S", 3, "申通快递"), YUANTONG("Y", 4, "圆通快递"), YUNDA("Y", 5, "韵达快递"), - EMS("E", 6, "EMS"), TIANTIAN("T", 7, "天天快递"), GUOTONG("G", 8, "国通快递"), SUER("S", 9, "速尔快递"), BAISHI("B", 10, "百世汇通"), LIANBANG("L", 11, "联邦快递"), - QUANFENG("Q", 12, "全峰快递"), ZAIJISONG("Z", 13, "宅急送"), QUANYI("Q", 14, "全一快递"), UPS("U", 15, "UPS快递"), - ZHONG_WAI_YUN("Z", 16, "中外运速递"),; - - private String initial; - private int logisticsCompanyId; - private String logisticsCompanyName; - - private LogisticsCompanyEnum(String initial, int logisticsCompanyId, String logisticsCompanyName) { - this.initial = initial; - this.logisticsCompanyId = logisticsCompanyId; - this.logisticsCompanyName = logisticsCompanyName; - } - - public String getInitial() { - return initial; - } - - public int getLogisticsCompanyId() { - return logisticsCompanyId; - } - - public String getLogisticsCompanyName() { - return logisticsCompanyName; - } - - } - - private static final Map ID_TO_NAME_LOGISTICS = new HashMap(); - - 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()); -// } - } + static int a; + + static class Node { + int coin; + + int index; + + int sum = 0; + + Node parent; + + int depth = 1; + + List children = new ArrayList<>(); + + public Node(int coin, int index) { + this.coin = coin; + this.index = index; + } + + public static void buildSum(Node node, int depth) { + node.sum = node.coin; + node.depth = depth; + if (!node.children.isEmpty()) { + for (Node childNode : node.children) { + buildSum(childNode, depth + 1); + node.sum += childNode.sum; + } + } + } + + } + + static String stringGameWinner(String s, String p) { + // Complete this function + boolean amandaWin; + if (s.length() < p.length()) { + amandaWin = false; + } else { + int distance = s.length() - p.length(); + if ((distance & 1) == 0 && s.contains(p)) { + amandaWin = true; + } else { + amandaWin = false; + } + } + return amandaWin ? "Amanda" : "Steven"; + } + + public static void main(String[] args) { + Scanner in = new Scanner(System.in); + // Return the number of non-empty perfect subsequences mod 1000000007 + int q = in.nextInt(); + PerfectString perfectString = new PerfectString(); + for (int a0 = 0; a0 < q; a0++) { + String s = in.next(); + long result = perfectString.perfectNum(s); + System.out.println(result); + } + } + + public class ListNode { + int val; + ListNode next; + ListNode(int x) { val = x; } + } + + public static ListNode rotateRight(ListNode head, int k) { + if (head == null || k <= 0) { + return head; + } + int length = 0; + ListNode node = head; + while (node != null) { + length += 1; + node = node.next; + } + if (length == 1) { + return head; + } + k = k % length; + ListNode forEnding = head; + for (int i = 0; i < length - k - 1; i++) { + forEnding = forEnding.next; + } + ListNode forHead = forEnding.next; + forEnding.next = null; + + ListNode actualEnd = forHead; + while (actualEnd.next != null) { + actualEnd = actualEnd.next; + } + + forEnding.next = null; + actualEnd.next = head; + return forHead; + } + + private static int addNode(int sum, Node first, Node second) { + boolean sub = false; + Node ancestor = null; + Node successor = null; + if (first.depth != second.depth) { + if (first.depth < second.depth) { + while (second.parent != null) { + second = second.parent; + if (first == second) { + sub = true; + ancestor = first; + successor = second; + break; + } + } + } else { + while (first.parent != null) { + first = first.parent; + if (first == second) { + sub = true; + ancestor = second; + successor = first; + break; + } + } + } + } + if (sub) { + return fixValue(sum - ancestor.sum, successor.sum, ancestor.sum - successor.sum); + } else { + return fixValue(first.sum, second.sum, sum - first.sum - second.sum); + } + } + + private static int fixValue(int first, int second, int left) { + if (first == second && first > left) { + return first - left; + } + if (second == left && second > first) { + return second - first; + } + if (first == left && first > second) { + return first - second; + } + return -1; + } + + private static void addRecursive(List powerList, int index, int sum, int[] result) { + if (sum >= result.length) { + return; + } + if (index >= powerList.size()) { + result[sum] += 1; + return; + } + addRecursive(powerList, index + 1, sum + powerList.get(index), result); + addRecursive(powerList, index + 1, sum, result); + } + + public class A { + + } + + public static class B { + } + + public enum LogisticsCompanyEnum { + + QITA("Q", 0, "其它"), SHUNFENG("S", 1, "顺丰速运"), ZHONGTONG("Z", 2, "中通快递"), SHENTONG("S", 3, "申通快递"), YUANTONG("Y", + 4, "圆通快递"), YUNDA("Y", 5, "韵达快递"), + EMS("E", 6, "EMS"), TIANTIAN("T", 7, "天天快递"), GUOTONG("G", 8, "国通快递"), SUER("S", 9, "速尔快递"), BAISHI("B", 10, + "百世汇通"), LIANBANG("L", 11, "联邦快递"), + QUANFENG("Q", 12, "全峰快递"), ZAIJISONG("Z", 13, "宅急送"), QUANYI("Q", 14, "全一快递"), UPS("U", 15, "UPS快递"), + ZHONG_WAI_YUN("Z", 16, "中外运速递"),; + + private String initial; + + private int logisticsCompanyId; + + private String logisticsCompanyName; + + private LogisticsCompanyEnum(String initial, int logisticsCompanyId, String logisticsCompanyName) { + this.initial = initial; + this.logisticsCompanyId = logisticsCompanyId; + this.logisticsCompanyName = logisticsCompanyName; + } + + public String getInitial() { + return initial; + } + + public int getLogisticsCompanyId() { + return logisticsCompanyId; + } + + public String getLogisticsCompanyName() { + return logisticsCompanyName; + } + + } + + private static final Map ID_TO_NAME_LOGISTICS = new HashMap(); + + 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 wordBreakList) { + if (index >= s.length()) { + wordBreakList.add(currentWord); + return; + } + for (int nextIndex = index; nextIndex < s.length(); nextIndex++) { + String tempString = s.substring(index, nextIndex + 1); + if (wordSet.contains(tempString)) { + String temp = currentWord.length() == 0 ? tempString : currentWord + " " + tempString; + breakWord(s, wordSet, nextIndex + 1, temp, wordBreakList); + } + } + } + +} diff --git a/src/main/java/org/wcong/test/algorithm/leetcode/string/WordSearch2.java b/src/main/java/org/wcong/test/algorithm/leetcode/string/WordSearch2.java new file mode 100644 index 0000000..d6dcac5 --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/leetcode/string/WordSearch2.java @@ -0,0 +1,56 @@ +package org.wcong.test.algorithm.leetcode.string; + +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +/** + * Given a 2D board and a list of words from the dictionary, + * find all words in the board. + * Each word must be constructed from letters of sequentially adjacent cell, + * where "adjacent" cells are those horizontally or vertically neighboring. + * The same letter cell may not be used more than once in a word. + * For example, + * Given words = ["oath","pea","eat","rain"] and board = + * [ + * ['o','a','a','n'], + * ['e','t','a','e'], + * ['i','h','k','r'], + * ['i','f','l','v'] + * ] + * Return ["eat","oath"]. + * + * @author wcong + * @since 26/05/2017 + */ +public class WordSearch2 { + + public List findWords(char[][] board, String[] words) { + Map> characterListMap = new HashMap<>(); + for (int rowIndex = 0; rowIndex < board.length; rowIndex++) { + char[] row = board[rowIndex]; + for (int columnIndex = 0; columnIndex < row.length; columnIndex++) { + char column = row[columnIndex]; + List indexList = characterListMap.get(column); + if (indexList == null) { + indexList = new LinkedList<>(); + characterListMap.put(column, indexList); + } + int[] index = new int[2]; + index[0] = rowIndex; + index[1] = columnIndex; + indexList.add(index); + } + } + List wordList = new LinkedList<>(); + for (String word : words) { + List firstIndexList = characterListMap.get(word.charAt(0)); + if (firstIndexList == null) { + continue; + } + boolean contains = false; + } + return wordList; + } +} diff --git a/src/main/java/org/wcong/test/algorithm/leetcode/string/WorldLadder.java b/src/main/java/org/wcong/test/algorithm/leetcode/string/WorldLadder.java new file mode 100644 index 0000000..1080362 --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/leetcode/string/WorldLadder.java @@ -0,0 +1,68 @@ +package org.wcong.test.algorithm.leetcode.string; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; + +/** + * @author wcong + * @since 2017/4/3 + */ +public class WorldLadder { + + public static void main(String[] args) { + new WorldLadder().findLadders("hot", "dog", + Arrays.asList(new String[] { "hot", "cog", "dog", "tot", "hog", "hop", "pot", "dot" })); + } + + private int minLength = Integer.MAX_VALUE; + + public List> findLadders(String beginWord, String endWord, List wordList) { + List> resultList = new LinkedList<>(); + List result = new LinkedList<>(); + result.add(beginWord); + findLadders(beginWord, endWord, wordList, result, resultList); + List> minResult = new LinkedList<>(); + for (List soloResult : resultList) { + if (soloResult.size() == minLength) { + minResult.add(soloResult); + } + } + return minResult; + } + + private void findLadders(String beginWord, String endWord, List wordList, List result, + List> resultList) { + if (beginWord.equals(endWord)) { + if (result.size() <= minLength) { + resultList.add(result); + minLength = result.size(); + } + return; + } + if (resultList.size() > minLength) { + return; + } + for (int i = 0; i < wordList.size(); i++) { + if (isOneWordDiffrent(beginWord, wordList.get(i))) { + List leftWordList = new ArrayList(); + leftWordList.addAll(wordList); + leftWordList.remove(i); + List leftResult = new ArrayList(result); + leftResult.add(wordList.get(i)); + findLadders(wordList.get(i), endWord, leftWordList, leftResult, resultList); + } + } + } + + private boolean isOneWordDiffrent(String word, String compare) { + int different = 0; + for (int i = 0; i < word.length(); i++) { + if (word.charAt(i) != compare.charAt(i)) { + different += 1; + } + } + return different == 1; + } +} diff --git a/src/main/java/org/wcong/test/algorithm/leetcode/tree/BinaryTreeMaximumSubPath.java b/src/main/java/org/wcong/test/algorithm/leetcode/tree/BinaryTreeMaximumSubPath.java new file mode 100644 index 0000000..21d5261 --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/leetcode/tree/BinaryTreeMaximumSubPath.java @@ -0,0 +1,41 @@ +package org.wcong.test.algorithm.leetcode.tree; + +/** + * Given a binary tree, find the maximum path sum. + * For this problem, + * a path is defined as any sequence of nodes from some starting node to any node in the tree along the parent-child connections. + * The path must contain at least one node and does not need to go through the root. + * + * @author wcong + * @since 05/05/2017 + */ +public class BinaryTreeMaximumSubPath { + + private int maxPath; + + public int maxPathSum(TreeNode root) { + maxPath = Integer.MIN_VALUE; + maxSubPathSum(root); + return maxPath; + } + + private int maxSubPathSum(TreeNode node) { + if (node == null) { + return 0; + } + int left = maxSubPathSum(node.left); + int right = maxSubPathSum(node.right); + int maxSum = node.val; + if (left > 0) { + maxSum += left; + } + if (right > 0) { + maxSum += right; + } + if (maxPath < maxSum) { + maxPath = maxSum; + } + int max = left > right ? left : right; + return max > 0 ? max + node.val : node.val; + } +} diff --git a/src/main/java/org/wcong/test/algorithm/leetcode/tree/BinaryTreePaths.java b/src/main/java/org/wcong/test/algorithm/leetcode/tree/BinaryTreePaths.java new file mode 100644 index 0000000..c5651ed --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/leetcode/tree/BinaryTreePaths.java @@ -0,0 +1,37 @@ +package org.wcong.test.algorithm.leetcode.tree; + +import java.util.ArrayList; +import java.util.List; + +/** + * given a binary tree,return all root-to-leaf path + * Created by wcong on 2017/4/1. + */ +public class BinaryTreePaths { + + static class TreeNode { + int value; + TreeNode left; + TreeNode right; + } + + public static void main(String[] args) { + + } + + public List paths(TreeNode treeNode) { + List path = new ArrayList<>(); + findPath(treeNode, "", path); + return path; + } + + private static void findPath(TreeNode treeNode, String prefix, List path) { + if (treeNode == null) { + path.add(prefix); + return; + } + prefix += treeNode.value; + findPath(treeNode.left, prefix, path); + findPath(treeNode.right, prefix, path); + } +} diff --git a/src/main/java/org/wcong/test/algorithm/leetcode/tree/InorderSuccessorInBST.java b/src/main/java/org/wcong/test/algorithm/leetcode/tree/InorderSuccessorInBST.java new file mode 100644 index 0000000..58534c8 --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/leetcode/tree/InorderSuccessorInBST.java @@ -0,0 +1,30 @@ +package org.wcong.test.algorithm.leetcode.tree; + +/** + * give a binary search tree and a node in it,find the inorder successor of the node in the bst + * test for inorder tree walk, + * if right child is not null,find the min node in left sub tree; + * if right child is null,find the last right ancestor. + * Created by wcong on 2017/4/1. + */ +public class InorderSuccessorInBST { + + public static void main(String[] args) { + + } + + public static TreeNode inOrderSuccessor(TreeNode root, TreeNode findNode) { + TreeNode lastLeftNode = null; + TreeNode compareNode = root; + while (compareNode != null) { + if (findNode.val < compareNode.val) { + lastLeftNode = compareNode; + compareNode = compareNode.left; + } else { + compareNode = compareNode.right; + } + } + return lastLeftNode; + } + +} diff --git a/src/main/java/org/wcong/test/algorithm/leetcode/tree/InvertBinaryTree.java b/src/main/java/org/wcong/test/algorithm/leetcode/tree/InvertBinaryTree.java new file mode 100644 index 0000000..1521d35 --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/leetcode/tree/InvertBinaryTree.java @@ -0,0 +1,46 @@ +package org.wcong.test.algorithm.leetcode.tree; + +import java.util.Stack; + +/** + * as the name says + * Created by wcong on 2017/4/1. + */ +public class InvertBinaryTree { + + public static void main(String[] args) { + + } + + public static void invert(TreeNode root) { + if (root == null) { + return; + } + TreeNode temp = root.left; + root.left = root.right; + root.right = temp; + invert(root.left); + invert(root.right); + } + + public static void invertLoop(TreeNode root) { + if (root == null) { + return; + } + Stack treeNodeStack = new Stack<>(); + treeNodeStack.push(root); + while (!treeNodeStack.isEmpty()) { + TreeNode treeNode = treeNodeStack.pop(); + TreeNode temp = treeNode.left; + treeNode.left = treeNode.right; + treeNode.right = temp; + if (treeNode.left != null) { + treeNodeStack.push(treeNode.left); + } + if (treeNode.right != null) { + treeNodeStack.push(treeNode.right); + } + } + } + +} diff --git a/src/main/java/org/wcong/test/algorithm/leetcode/tree/LowestCommonAncestorOfABinaryTree.java b/src/main/java/org/wcong/test/algorithm/leetcode/tree/LowestCommonAncestorOfABinaryTree.java new file mode 100644 index 0000000..5b27b0c --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/leetcode/tree/LowestCommonAncestorOfABinaryTree.java @@ -0,0 +1,54 @@ +package org.wcong.test.algorithm.leetcode.tree; + +import java.util.LinkedList; +import java.util.List; + +/** + * give a binary tree, find the lowest common ancestor of given two node + * Created by wcong on 2017/4/1. + */ +public class LowestCommonAncestorOfABinaryTree { + + public static void main(String[] args) { + + } + + public static TreeNode lowestCommonAncestor(TreeNode root, TreeNode node1, TreeNode node2) { + List path1 = new LinkedList<>(); + List path2 = new LinkedList<>(); + path1.add(root); + path2.add(root); + findNode(root, node1, path1); + findNode(root, node2, path2); + for (int i = 0; i < path1.size() && i < path2.size(); i++) { + if (path1.get(i) != path2.get(i)) { + return path1.get(i - 1); + } + } + return null; + } + + private static boolean findNode(TreeNode treeNode, TreeNode findNode, List path) { + if (treeNode.val == findNode.val) { + return true; + } else { + if (treeNode.left != null) { + path.add(treeNode.left); + if (findNode(treeNode.left, findNode, path)) { + return true; + } else { + path.remove(path.size() - 1); + } + } + if (treeNode.right != null) { + path.add(treeNode.right); + if (findNode(treeNode.right, findNode, path)) { + return true; + } else { + path.remove(path.size() - 1); + } + } + return false; + } + } +} diff --git a/src/main/java/org/wcong/test/algorithm/leetcode/tree/MaximumPathSum.java b/src/main/java/org/wcong/test/algorithm/leetcode/tree/MaximumPathSum.java new file mode 100644 index 0000000..2cd227a --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/leetcode/tree/MaximumPathSum.java @@ -0,0 +1,39 @@ +package org.wcong.test.algorithm.leetcode.tree; + +/** + * give a binary tree,find the maximum path sum for any path ,not have to include the root,just path + * Created by wcong on 2017/4/1. + */ +public class MaximumPathSum { + + public static void main(String[] args) { + + } + + static class TreeNode { + int value; + TreeNode left; + TreeNode right; + } + + static int max = Integer.MIN_VALUE; + + public static int maximumPathSum(TreeNode root) { + sumTree(root); + return max; + } + + private static int sumTree(TreeNode treeNode) { + if (treeNode == null) { + return 0; + } + int sum = treeNode.value; + sum += Math.max(sumTree(treeNode.left), 0); + sum += Math.max(sumTree(treeNode.right), 0); + if (sum > max) { + max = sum; + } + return sum; + } + +} diff --git a/src/main/java/org/wcong/test/algorithm/leetcode/tree/SumOfLeftLeaves.java b/src/main/java/org/wcong/test/algorithm/leetcode/tree/SumOfLeftLeaves.java new file mode 100644 index 0000000..6bcffa2 --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/leetcode/tree/SumOfLeftLeaves.java @@ -0,0 +1,35 @@ +package org.wcong.test.algorithm.leetcode.tree; + +import java.util.Stack; + +/** + * sum all of the leaves of the tree + * Created by wcong on 2017/4/1. + */ +public class SumOfLeftLeaves { + + public static void main(String[] args) { + + } + + public static int sumLeft(TreeNode root) { + int sum = 0; + if (root == null) { + return sum; + } + Stack treeNodeStack = new Stack<>(); + treeNodeStack.push(root); + while (!treeNodeStack.isEmpty()) { + TreeNode treeNode = treeNodeStack.pop(); + if (treeNode.right != null) { + treeNodeStack.push(treeNode.right); + } + if (treeNode.left != null) { + sum += treeNode.left.val; + treeNodeStack.push(treeNode.left); + } + } + return sum; + } + +} diff --git a/src/main/java/org/wcong/test/algorithm/leetcode/tree/TreeNode.java b/src/main/java/org/wcong/test/algorithm/leetcode/tree/TreeNode.java new file mode 100644 index 0000000..bdb9ad8 --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/leetcode/tree/TreeNode.java @@ -0,0 +1,14 @@ +package org.wcong.test.algorithm.leetcode.tree; + +/** + * Created by wcong on 2017/4/1. + */ +public class TreeNode { + + public int val; + + public TreeNode left; + + public TreeNode right; + +} diff --git a/src/main/java/org/wcong/test/algorithm/leetcode/tree/ValidateBinaryTree.java b/src/main/java/org/wcong/test/algorithm/leetcode/tree/ValidateBinaryTree.java new file mode 100644 index 0000000..576bdd1 --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/leetcode/tree/ValidateBinaryTree.java @@ -0,0 +1,29 @@ +package org.wcong.test.algorithm.leetcode.tree; + +/** + * give a binary tree,test if it is a binary tree + * Created by wcong on 2017/4/1. + */ +public class ValidateBinaryTree { + + public static void main(String args) { + } + + static int max = Integer.MIN_VALUE; + + public static boolean validate(TreeNode treeNode) { + if (treeNode == null) { + return true; + } + if (!validate(treeNode.left)) { + return false; + } + if (treeNode.val >= max) { + max = treeNode.val; + } else { + return false; + } + return validate(treeNode.right); + } + +} diff --git a/src/main/java/org/wcong/test/algorithm/tree/BinaryTree.java b/src/main/java/org/wcong/test/algorithm/tree/BinaryTree.java new file mode 100644 index 0000000..2adafaa --- /dev/null +++ b/src/main/java/org/wcong/test/algorithm/tree/BinaryTree.java @@ -0,0 +1,112 @@ +package org.wcong.test.algorithm.tree; + +/** + * Created by wcong on 2017/3/17. + */ +public class BinaryTree { + + Node root; + + + public static class Node { + + public Node(int key) { + this.key = key; + } + + public int key; + + public Node left; + + public Node right; + + } + + public Node root() { + return root; + } + + public void addNode(int key) { + if (root == null) { + root = new Node(key); + return; + } + addNodeInternal(key, root); + } + + public void deleteNode(int key) { + if (root == null) { + return; + } + if (root.key == key) { + if (root.right == null) { + if (root.left == null) { + root = null; + } else { + root = root.left; + } + } else { + Node parent = root; + Node replace = root.right; + while (replace.left != null) { + parent = replace; + replace = replace.left; + } + if (parent.left == replace) { + parent.left = null; + } else { + parent.right = replace.right; + } + root.key = replace.key; + } + } else { + if (key < root.key) { + deleteNodeInternal(root, root.left, key); + } else { + deleteNodeInternal(root, root.right, key); + } + } + } + + + private void deleteNodeInternal(Node parent, Node node, int key) { + if (node == null) { + return; + } + if (node.key == key) { + if (node.right == null && node.left == null) { + if (parent.left == node) { + parent.left = null; + } else { + parent.right = null; + } + } else if (node.right == null) { + + } + } else if (node.key < key) { + deleteNodeInternal(node, node.right, key); + } else { + deleteNodeInternal(node, node.left, key); + } + } + + private void addNodeInternal(int key, Node node) { + if (node.key == key) { + return; + } + if (key < node.key) { + if (node.left == null) { + node.left = new Node(key); + } else { + addNodeInternal(key, node.left); + } + } else { + if (node.right == null) { + node.right = new Node(key); + } else { + addNodeInternal(key, node.right); + } + } + } + +} diff --git a/src/main/java/org/wcong/test/autovalue/AutoAnnotationTest.java b/src/main/java/org/wcong/test/autovalue/AutoAnnotationTest.java new file mode 100644 index 0000000..9eedd6d --- /dev/null +++ b/src/main/java/org/wcong/test/autovalue/AutoAnnotationTest.java @@ -0,0 +1,19 @@ +package org.wcong.test.autovalue; + +import com.google.auto.value.AutoAnnotation; + +/** + * Created by hzwangcong on 2016/11/22. + */ +public class AutoAnnotationTest { + + public static void main(String[] args) { + MyAnnotation myAnnotation = new MyAnnotationImpl(); + System.out.println(myAnnotation("hello")); + } + + @AutoAnnotation + public static MyAnnotation myAnnotation(String value) { + return new AutoAnnotation_AutoAnnotationTest_myAnnotation(value); + } +} diff --git a/src/main/java/org/wcong/test/autovalue/AutoValueTest.java b/src/main/java/org/wcong/test/autovalue/AutoValueTest.java new file mode 100644 index 0000000..bfc34bb --- /dev/null +++ b/src/main/java/org/wcong/test/autovalue/AutoValueTest.java @@ -0,0 +1,11 @@ +package org.wcong.test.autovalue; + +/** + * Created by wcong on 2016/11/22. + */ +public class AutoValueTest { + public static void main(String[] args) { + MyClass myClass = MyClass.create("world"); + System.out.println(myClass); + } +} diff --git a/src/main/java/org/wcong/test/autovalue/MyAnnotation.java b/src/main/java/org/wcong/test/autovalue/MyAnnotation.java new file mode 100644 index 0000000..084d22f --- /dev/null +++ b/src/main/java/org/wcong/test/autovalue/MyAnnotation.java @@ -0,0 +1,15 @@ +package org.wcong.test.autovalue; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Created by hzwangcong on 2016/11/22. + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.SOURCE) +public @interface MyAnnotation { + String value(); +} diff --git a/src/main/java/org/wcong/test/autovalue/MyAnnotationImpl.java b/src/main/java/org/wcong/test/autovalue/MyAnnotationImpl.java new file mode 100644 index 0000000..4e627bf --- /dev/null +++ b/src/main/java/org/wcong/test/autovalue/MyAnnotationImpl.java @@ -0,0 +1,16 @@ +package org.wcong.test.autovalue; + +import java.lang.annotation.Annotation; + +/** + * Created by hzwangcong on 2016/11/22. + */ +public class MyAnnotationImpl implements MyAnnotation { + public String value() { + return null; + } + + public Class annotationType() { + return null; + } +} diff --git a/src/main/java/org/wcong/test/autovalue/MyAutoValueClassTest.java b/src/main/java/org/wcong/test/autovalue/MyAutoValueClassTest.java new file mode 100644 index 0000000..318a24b --- /dev/null +++ b/src/main/java/org/wcong/test/autovalue/MyAutoValueClassTest.java @@ -0,0 +1,15 @@ +package org.wcong.test.autovalue; + +/** + * Created by hzwangcong on 2016/11/25. + */ +@MyAutoValue +public class MyAutoValueClassTest { + + private String a; + + private String b; + + private int c; + +} diff --git a/src/main/java/org/wcong/test/autovalue/MyAutoValueTest.java b/src/main/java/org/wcong/test/autovalue/MyAutoValueTest.java new file mode 100644 index 0000000..da02751 --- /dev/null +++ b/src/main/java/org/wcong/test/autovalue/MyAutoValueTest.java @@ -0,0 +1,14 @@ +package org.wcong.test.autovalue; + +/** + * Created by wcong on 2016/11/26. + */ +public class MyAutoValueTest { + public static void main(String[] args) { + org.wcong.test.autovalue.MyAutoValueClassTest_MyAutoValue myAutoValueClassTest_myAutoValue = new org.wcong.test.autovalue.MyAutoValueClassTest_MyAutoValue(); + myAutoValueClassTest_myAutoValue.setA("a"); + myAutoValueClassTest_myAutoValue.setB("b"); + myAutoValueClassTest_myAutoValue.setC(1); + System.out.println(myAutoValueClassTest_myAutoValue.toString()); + } +} diff --git a/src/main/java/org/wcong/test/autovalue/MyClass.java b/src/main/java/org/wcong/test/autovalue/MyClass.java new file mode 100644 index 0000000..679a493 --- /dev/null +++ b/src/main/java/org/wcong/test/autovalue/MyClass.java @@ -0,0 +1,15 @@ +package org.wcong.test.autovalue; + +import com.google.auto.value.AutoValue; + +/** + * Created by wcong on 2016/11/22. + */ +@AutoValue +abstract class MyClass { + static MyClass create(String hello) { + return new AutoValue_MyClass(hello); + } + + abstract String hello(); +} diff --git a/src/main/java/org/wcong/test/concurrent/Basic.java b/src/main/java/org/wcong/test/concurrent/Basic.java new file mode 100644 index 0000000..29e0c0c --- /dev/null +++ b/src/main/java/org/wcong/test/concurrent/Basic.java @@ -0,0 +1,63 @@ +package org.wcong.test.concurrent; + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +/** + * @author wcong + * @since 29/04/2017 + */ +public class Basic { + + public static class MyThread extends Thread { + + private CountDownLatch countDownLatch; + + public MyThread(CountDownLatch countDownLatch) { + this.countDownLatch = countDownLatch; + } + + @Override + public void run() { + try { + countDownLatch.await(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + System.out.println("I'm running"); + } + } + + public static class MyRunner implements Runnable { + + private CountDownLatch countDownLatch; + + public MyRunner(CountDownLatch countDownLatch) { + this.countDownLatch = countDownLatch; + } + + @Override + public void run() { + try { + countDownLatch.await(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + System.out.println("I'm running too"); + } + } + + public static void main(String[] args) throws InterruptedException { + + CountDownLatch countDownLatch = new CountDownLatch(1); + Thread thread = new MyThread(countDownLatch); + thread.start(); + Thread secondThread = new Thread(new MyRunner(countDownLatch)); + secondThread.start(); + System.out.println("wait for it"); + thread.join(); + countDownLatch.countDown(); + TimeUnit.MILLISECONDS.sleep(1000); + } + +} diff --git a/src/main/java/org/wcong/test/concurrent/CountDownLatchThread.java b/src/main/java/org/wcong/test/concurrent/CountDownLatchThread.java new file mode 100644 index 0000000..dba2fa5 --- /dev/null +++ b/src/main/java/org/wcong/test/concurrent/CountDownLatchThread.java @@ -0,0 +1,27 @@ +package org.wcong.test.concurrent; + +import java.util.concurrent.CountDownLatch; + +/** + * @author wcong + * @since 30/04/2017 + */ +public class CountDownLatchThread implements Runnable { + + private CountDownLatch countDownLatch; + + public CountDownLatchThread(CountDownLatch countDownLatch) { + this.countDownLatch = countDownLatch; + } + + public void run() { + System.out.println("wait for it"); + countDownLatch.countDown(); + try { + countDownLatch.await(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + System.out.println("start"); + } +} diff --git a/src/main/java/org/wcong/test/concurrent/CyclicBarrierPrint.java b/src/main/java/org/wcong/test/concurrent/CyclicBarrierPrint.java new file mode 100644 index 0000000..e3fec8a --- /dev/null +++ b/src/main/java/org/wcong/test/concurrent/CyclicBarrierPrint.java @@ -0,0 +1,38 @@ +package org.wcong.test.concurrent; + +import java.util.concurrent.BrokenBarrierException; +import java.util.concurrent.CyclicBarrier; + +/** + * @author wcong + * @since 30/04/2017 + */ +public class CyclicBarrierPrint implements Runnable { + + private CyclicBarrier cyclicBarrier; + + public CyclicBarrierPrint(CyclicBarrier cyclicBarrier) { + this.cyclicBarrier = cyclicBarrier; + } + + @Override + public void run() { + System.out.println("I'm ready"); + try { + cyclicBarrier.await(); + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (BrokenBarrierException e) { + e.printStackTrace(); + } + System.out.println("I'm ready 1"); + try { + cyclicBarrier.await(); + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (BrokenBarrierException e) { + e.printStackTrace(); + } + System.out.println("we are finished"); + } +} diff --git a/src/main/java/org/wcong/test/concurrent/ExceptionHandler.java b/src/main/java/org/wcong/test/concurrent/ExceptionHandler.java new file mode 100644 index 0000000..f0cadd9 --- /dev/null +++ b/src/main/java/org/wcong/test/concurrent/ExceptionHandler.java @@ -0,0 +1,30 @@ +package org.wcong.test.concurrent; + +/** + * @author wcong + * @since 29/04/2017 + */ +public class ExceptionHandler { + + public static class MyThread extends Thread { + public void run() { + throw new RuntimeException("hello exception"); + } + } + + public static class MyExceptionHandler implements Thread.UncaughtExceptionHandler { + + @Override + public void uncaughtException(Thread t, Throwable e) { + System.out.println(e.toString()); + } + } + + public static void main(String[] args) { + MyThread myThread = new MyThread(); + myThread.setUncaughtExceptionHandler(new MyExceptionHandler()); + myThread.start(); + System.out.println("haha"); + } + +} diff --git a/src/main/java/org/wcong/test/concurrent/PhaserPrint.java b/src/main/java/org/wcong/test/concurrent/PhaserPrint.java new file mode 100644 index 0000000..4f22131 --- /dev/null +++ b/src/main/java/org/wcong/test/concurrent/PhaserPrint.java @@ -0,0 +1,30 @@ +package org.wcong.test.concurrent; + +import java.util.concurrent.Phaser; + +/** + * @author wcong + * @since 30/04/2017 + */ +public class PhaserPrint implements Runnable { + + private Phaser phaser; + + public PhaserPrint(Phaser phaser) { + this.phaser = phaser; + } + + @Override + public void run() { + System.out.println("thread:" + Thread.currentThread().getId() + ":print 1"); + phaser.arriveAndAwaitAdvance(); + System.out.println("thread:" + Thread.currentThread().getId() + ":print 2"); + phaser.arriveAndAwaitAdvance(); + System.out.println("thread:" + Thread.currentThread().getId() + ":print 3"); + phaser.arriveAndAwaitAdvance(); + System.out.println("thread:" + Thread.currentThread().getId() + ":print 4"); + phaser.arriveAndAwaitAdvance(); + System.out.println("thread:" + Thread.currentThread().getId() + ":finished"); + phaser.arriveAndDeregister(); + } +} diff --git a/src/main/java/org/wcong/test/concurrent/ProducerAndComsumer.java b/src/main/java/org/wcong/test/concurrent/ProducerAndComsumer.java new file mode 100644 index 0000000..8148f42 --- /dev/null +++ b/src/main/java/org/wcong/test/concurrent/ProducerAndComsumer.java @@ -0,0 +1,46 @@ +package org.wcong.test.concurrent; + +import java.util.LinkedList; + +/** + * @author wcong + * @since 29/04/2017 + */ +public class ProducerAndComsumer { + + private static class Queue { + + private int maxSize; + + public Queue(int maxSize) { + this.maxSize = maxSize; + } + + LinkedList integerList = new LinkedList<>(); + + public synchronized Integer get() { + while (integerList.isEmpty()) { + try { + wait(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + return integerList.pop(); + + } + + public synchronized void add(Integer num) { + while (maxSize == integerList.size()) { + try { + wait(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + integerList.push(num); + } + + } + +} diff --git a/src/main/java/org/wcong/test/concurrent/SemaphorePrint.java b/src/main/java/org/wcong/test/concurrent/SemaphorePrint.java new file mode 100644 index 0000000..d50acc8 --- /dev/null +++ b/src/main/java/org/wcong/test/concurrent/SemaphorePrint.java @@ -0,0 +1,25 @@ +package org.wcong.test.concurrent; + +import java.util.concurrent.Semaphore; + +/** + * @author wcong + * @since 30/04/2017 + */ +public class SemaphorePrint { + + private Semaphore semaphore = new Semaphore(2); + + public void print() { + try { + semaphore.acquire(); + System.out.println("acquire the semaphore :" + Thread.currentThread().getId() + ";"); + } catch (InterruptedException e) { + e.printStackTrace(); + } finally { + System.out.println("release the semaphore :" + Thread.currentThread().getId() + ";"); + semaphore.release(); + } + } + +} diff --git a/src/main/java/org/wcong/test/concurrent/SynchronizedMethod.java b/src/main/java/org/wcong/test/concurrent/SynchronizedMethod.java new file mode 100644 index 0000000..ce0d666 --- /dev/null +++ b/src/main/java/org/wcong/test/concurrent/SynchronizedMethod.java @@ -0,0 +1,60 @@ +package org.wcong.test.concurrent; + +import java.util.LinkedList; + +/** + * @author wcong + * @since 30/04/2017 + */ +public class SynchronizedMethod { + + LinkedList numList = new LinkedList<>(); + + public synchronized Integer get() { + System.out.println("Thread" + Thread.currentThread().getId() + "get the lock and sleep"); + try { + Thread.sleep(5000L); + } catch (InterruptedException e) { + e.printStackTrace(); + } + return numList.pop(); + } + + public synchronized void push(Integer num) { + System.out.println("Thread" + Thread.currentThread().getId() + "get the lock and sleep"); + try { + Thread.sleep(5000L); + } catch (InterruptedException e) { + e.printStackTrace(); + } + numList.push(num); + } + + public static class MyGetThread extends Thread { + + private SynchronizedMethod synchronizedMethod; + + public MyGetThread(SynchronizedMethod synchronizedMethod) { + this.synchronizedMethod = synchronizedMethod; + } + + public void run() { + System.out.println("get " + synchronizedMethod.get()); + } + } + + public static class MyPutThread extends Thread { + + private SynchronizedMethod synchronizedMethod; + + public MyPutThread(SynchronizedMethod synchronizedMethod) { + this.synchronizedMethod = synchronizedMethod; + } + + public void run() { + synchronizedMethod.push(1); + System.out.println("put 1 "); + } + } + +} diff --git a/src/main/java/org/wcong/test/concurrent/ThreadWait.java b/src/main/java/org/wcong/test/concurrent/ThreadWait.java new file mode 100644 index 0000000..0a834a4 --- /dev/null +++ b/src/main/java/org/wcong/test/concurrent/ThreadWait.java @@ -0,0 +1,33 @@ +package org.wcong.test.concurrent; + +import java.util.concurrent.TimeUnit; + +/** + * @author wcong + * @since 29/04/2017 + */ +public class ThreadWait { + + public static class MyThread extends Thread { + public MyThread(String name) { + setName(name); + } + + public void run() { + TimeUnit.MILLISECONDS.toSeconds(1000); + System.out.println(getName()); + } + } + + public static void main(String[] args) throws InterruptedException { + MyThread thread1 = new MyThread("1"); + MyThread thread2 = new MyThread("2"); + thread1.start(); + thread2.start(); + thread1.join(); + thread2.join(); + System.out.println("finished"); + + } + +} diff --git a/src/main/java/org/wcong/test/concurrent/ThreadWithStop.java b/src/main/java/org/wcong/test/concurrent/ThreadWithStop.java new file mode 100644 index 0000000..33a5852 --- /dev/null +++ b/src/main/java/org/wcong/test/concurrent/ThreadWithStop.java @@ -0,0 +1,27 @@ +package org.wcong.test.concurrent; + +/** + * @author wcong + * @since 30/04/2017 + */ +public class ThreadWithStop extends Thread { + + private boolean stop; + + public void setStop(boolean stop) { + this.stop = stop; + } + + public void run() { + while (!stop) { + try { + sleep(1000L); + } catch (InterruptedException e) { + e.printStackTrace(); + } + System.out.println("I'm running"); + } + System.out.println("I stopped"); + } + +} diff --git a/src/main/java/org/wcong/test/dagger/CircleBindingTest.java b/src/main/java/org/wcong/test/dagger/CircleBindingTest.java new file mode 100644 index 0000000..d126bc3 --- /dev/null +++ b/src/main/java/org/wcong/test/dagger/CircleBindingTest.java @@ -0,0 +1,72 @@ +package org.wcong.test.dagger; + +import dagger.Binds; +import dagger.Component; +import dagger.Module; +import dagger.Provides; + +import javax.inject.Inject; +import javax.inject.Singleton; + +/** + * @author wcong + * @since 2016/11/7 + */ +public class CircleBindingTest { + public static void main(String[] args) { + MyComponent myComponent = DaggerCircleBindingTest_MyComponent.builder().build(); + myComponent.getExportClass().print(); + } + + @Singleton + @Component(modules = { MyBindModule.class, MyProvidesModule.class }) + interface MyComponent { + ExportClass getExportClass(); + } + + static class ExportClass { + private final MyClass myClass; + + + @Inject + public ExportClass(MyClass myClass) { + this.myClass = myClass; + } + + public void print(){ + + } + } + + @Module + static class MyProvidesModule { + @Provides + MyParam getMyParam() { + return new MyParam(); + } + } + + @Module + abstract class MyBindModule { + + @Binds + abstract MyClass myClass(MySubClass a); + } + + static class MyClass { + + } + + static class MySubClass extends MyClass { + + private final MyParam myParam; + + @Inject + public MySubClass(MyParam myParam) { + this.myParam = myParam; + } + } + + static class MyParam { + } +} diff --git a/src/main/java/org/wcong/test/dagger/DaggerTest.java b/src/main/java/org/wcong/test/dagger/DaggerTest.java new file mode 100644 index 0000000..3d757d0 --- /dev/null +++ b/src/main/java/org/wcong/test/dagger/DaggerTest.java @@ -0,0 +1,81 @@ +package org.wcong.test.dagger; + +import dagger.Binds; +import dagger.Component; +import dagger.Lazy; +import dagger.Module; +import dagger.Provides; + +import javax.inject.Inject; +import javax.inject.Singleton; + +/** + * @author wcong + * @since 2016/11/2 + */ +public class DaggerTest { + public static void main(String[] args) { + Coffee coffee = DaggerDaggerTest_Coffee.builder().build(); + coffee.maker().brew(); + } + + @Singleton + @Component(modules = { DripCoffeeModule.class }) + public interface Coffee { + CoffeeMaker maker(); + } + + @Module(includes = PumpModule.class) + static class DripCoffeeModule { + @Provides + @Singleton + Heater provideHeater() { + return new ElectricHeater(); + } + } + + @Module + abstract class PumpModule { + @Binds + abstract Pump providePump(Thermosiphon pump); + } + + static class CoffeeMaker { + Lazy heater; + + Pump pump; + + @Inject + CoffeeMaker(Lazy heater, Pump pump) { + this.heater = heater; + this.pump = pump; + } + + public void brew() { + pump.pump(); + } + } + + interface Heater { + } + + interface Pump { + void pump(); + } + + static class Thermosiphon implements Pump { + private final Heater heater; + + @Inject + Thermosiphon(Heater heater) { + this.heater = heater; + } + + public void pump() { + System.out.println(heater); + } + } + + static class ElectricHeater implements Heater { + } +} diff --git a/src/main/java/org/wcong/test/dagger/annotation/MyAnnotation.java b/src/main/java/org/wcong/test/dagger/annotation/MyAnnotation.java new file mode 100644 index 0000000..7d8c474 --- /dev/null +++ b/src/main/java/org/wcong/test/dagger/annotation/MyAnnotation.java @@ -0,0 +1,17 @@ +package org.wcong.test.dagger.annotation; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * @author wcong + * @since 2016/11/4 + */ +@Retention(RetentionPolicy.SOURCE) +@Documented +@Target(ElementType.TYPE) +public @interface MyAnnotation { +} diff --git a/src/main/java/org/wcong/test/datastructure/BinarySearchTree.java b/src/main/java/org/wcong/test/datastructure/BinarySearchTree.java new file mode 100644 index 0000000..3757dc0 --- /dev/null +++ b/src/main/java/org/wcong/test/datastructure/BinarySearchTree.java @@ -0,0 +1,206 @@ +package org.wcong.test.datastructure; + +import java.util.Stack; + +/** + * search,add,delete,traversal for binary search tree + * minimum, maximize, floor, ceiling,selection, rank, + * Created by wcong on 2017/4/5. + */ +public class BinarySearchTree { + + private static class Node { + T value; + Node left; + Node right; + } + + private Node root; + + public Node findIterative(T value) { + Node node = root; + while (node != null) { + if (node.value.equals(value)) { + return node; + } else if (node.value.compareTo(value) > 0) { + node = node.left; + } else { + node = node.right; + } + } + return null; + } + + public Node findRecursive(T value) { + return findNode(root, value); + } + + private Node findNode(Node node, T value) { + if (node == null) { + return null; + } + if (node.value == value) { + return node; + } else if (node.value.compareTo(value) > 0) { + return findNode(node.left, value); + } else { + return findNode(node.right, value); + } + } + + public void insertIterative(T value) { + if (root == null) { + root = new Node<>(); + root.value = value; + return; + } + Node parent = root; + Node node = root; + while (node != null) { + if (node.value.equals(value)) { + return; + } else if (node.value.compareTo(value) > 0) { + parent = node; + node = node.left; + } else { + parent = node; + node = node.right; + } + } + Node insertNode = new Node<>(); + insertNode.value = value; + if (parent.value.compareTo(value) > 0) { + parent.left = insertNode; + } else { + parent.right = insertNode; + } + } + + public void insertRecursive(T value) { + if (root == null) { + root = new Node<>(); + root.value = value; + return; + } + insertNode(root, value); + } + + private void insertNode(Node node, T value) { + if (node == null || node.value.equals(value)) { + return; + } + if (node.value.compareTo(value) > 0) { + if (node.left != null) { + insertNode(node.left, value); + } else { + Node insertNode = new Node<>(); + node.value = value; + node.left = insertNode; + } + } else { + if (node.right != null) { + insertNode(node.right, value); + } else { + Node insertNode = new Node<>(); + node.value = value; + node.right = insertNode; + } + } + } + + public Node deleteMin(Node parent, Node node) { + if (node.left != null) { + return deleteMin(node, node.left); + } + if (parent.left == node) { + parent.left = node.right; + } else { + parent.right = node.right; + } + return node; + } + + private void deleteIterative(T value) { + Node parent = null; + Node node = root; + while (node != null) { + if (node.value.equals(value)) { + break; + } else if (node.value.compareTo(value) > 0) { + parent = node; + node = node.left; + } else { + parent = node; + node = node.right; + } + } + if (node == null) { + return; + } + if (parent == null) { + if (node.right == null) { + root = node.left; + } else { + root = deleteMin(root, root.left); + } + } else { + if (node.right == null) { + if (parent.left == node) { + parent.left = node.left; + } else { + parent.right = node.left; + } + } else { + Node rightMin = deleteMin(node, node.right); + rightMin.left = node.left; + rightMin.right = node.right; + if (parent.left == node) { + parent.left = rightMin; + } else { + parent.right = rightMin; + } + } + } + } + + public void inOrderTraversal() { + inOrderTraversal(root); + } + + private void inOrderTraversal(Node node) { + if (node == null) { + return; + } + inOrderTraversal(node.left); + System.out.println(node.value); + inOrderTraversal(node.right); + } + + private void inOrderTravelsalIterative() { + + } + + private void preOrderTraversalIterative() { + Stack> stack = new Stack<>(); + stack.push(root); + while (!stack.isEmpty()) { + Node node = stack.pop(); + System.out.println(node.value); + if (node.right != null) { + stack.push(node.right); + } + if (node.left != null) { + stack.push(node.left); + } + } + } + + private void postOrderTraversalIterative() { + Stack> stack = new Stack<>(); + stack.push(root); + while (!stack.isEmpty()) { + Node node = stack.pop(); + } + } + +} diff --git a/src/main/java/org/wcong/test/datastructure/LinkedList.java b/src/main/java/org/wcong/test/datastructure/LinkedList.java new file mode 100644 index 0000000..84cf1f6 --- /dev/null +++ b/src/main/java/org/wcong/test/datastructure/LinkedList.java @@ -0,0 +1,67 @@ +package org.wcong.test.datastructure; + +/** + * search,insert,delete for a linked list + * Created by wcong on 2017/4/5. + */ +public class LinkedList { + + private static class Node { + T value; + Node next; + } + + private Node root; + + public Node find(T value) { + Node node = root; + while (root != null) { + if (root.value.equals(value)) { + return node; + } + node = node.next; + } + return null; + } + + public void insert(T value) { + if (root == null) { + Node insert = new Node<>(); + insert.value = value; + root = insert; + return; + } + Node node = root; + while (true) { + if (node.value == value) { + return; + } + if (node.next == null) { + break; + } + node = node.next; + } + Node insert = new Node<>(); + insert.value = value; + node.next = insert; + } + + public void delete(T value) { + if (root == null) { + return; + } + if (root.value.equals(value)) { + root = root.next; + } + Node parent = root; + Node node = root.next; + while (node != null && node.value != value) { + parent = node; + node = node.next; + } + if (node != null) { + parent.next = node.next; + } + } + +} diff --git a/src/main/java/org/wcong/test/datastructure/package-info.java b/src/main/java/org/wcong/test/datastructure/package-info.java new file mode 100644 index 0000000..3d8954f --- /dev/null +++ b/src/main/java/org/wcong/test/datastructure/package-info.java @@ -0,0 +1,5 @@ +/** + * most data structure i should know + * Created by wcong on 2017/4/5. + */ +package org.wcong.test.datastructure; \ No newline at end of file diff --git a/src/main/java/org/wcong/test/guice/GuiceTest.java b/src/main/java/org/wcong/test/guice/GuiceTest.java new file mode 100644 index 0000000..3d315bb --- /dev/null +++ b/src/main/java/org/wcong/test/guice/GuiceTest.java @@ -0,0 +1,63 @@ +package org.wcong.test.guice; + +import com.google.inject.AbstractModule; +import com.google.inject.Guice; +import com.google.inject.Injector; +import com.google.inject.TypeLiteral; +import com.google.inject.matcher.Matcher; +import com.google.inject.spi.ProvisionListener; +import com.google.inject.spi.TypeEncounter; +import com.google.inject.spi.TypeListener; + +/** + * @author wcong + * @since 2016/10/29 + */ +public class GuiceTest { + + public static void main(String[] args) { + Injector injector = Guice.createInjector(new AbstractModule() { + @Override + protected void configure() { + bind(BindClass.class).toInstance(new BindClass()); + bindListener(new MyMatcher(), new MyTypeListener()); + bindListener(new MyMatcher(), new MyProvisionListener()); + } + }); + System.out.println(injector.getInstance(BindClass.class).message); + } + + public static class BindClass { + public String message = "hello world"; + } + + public static class MyMatcher implements Matcher { + + public boolean matches(Object o) { + return true; + } + + public Matcher and(Matcher other) { + return null; + } + + public Matcher or(Matcher other) { + return null; + } + } + + public static class MyTypeListener implements TypeListener { + + public void hear(TypeLiteral type, TypeEncounter encounter) { + System.out.println("hehehe"); + } + } + + public static class MyProvisionListener implements ProvisionListener { + + public void onProvision(ProvisionInvocation provision) { + System.out.println("hahaha"); + } + } + +} diff --git a/src/main/java/org/wcong/test/guice/MapBinderTest.java b/src/main/java/org/wcong/test/guice/MapBinderTest.java new file mode 100644 index 0000000..96ebdf6 --- /dev/null +++ b/src/main/java/org/wcong/test/guice/MapBinderTest.java @@ -0,0 +1,42 @@ +package org.wcong.test.guice; + +import com.google.inject.AbstractModule; +import com.google.inject.Guice; +import com.google.inject.Inject; +import com.google.inject.Injector; +import com.google.inject.multibindings.MapBinder; + +import java.util.Map; + +/** + * @author wcong + * @since 2016/10/31 + */ +public class MapBinderTest { + public static void main(String[] args) { + Injector injector = Guice.createInjector(new AbstractModule() { + @Override + protected void configure() { + MapBinder mapBinder = MapBinder.newMapBinder(binder(), String.class, String.class); + mapBinder.addBinding("hello").toInstance("world"); + binder().bind(MapContainer.class).asEagerSingleton(); + } + }); + MapContainer mapContainer = injector.getInstance(MapContainer.class); + System.out.println(mapContainer.toString()); + } + + public static class MapContainer { + + private Map data; + + @Inject + public MapContainer(Map data) { + this.data = data; + } + + public String toString() { + return data.toString(); + } + } +} diff --git a/src/main/java/org/wcong/test/guice/SetBinderTest.java b/src/main/java/org/wcong/test/guice/SetBinderTest.java new file mode 100644 index 0000000..5d52762 --- /dev/null +++ b/src/main/java/org/wcong/test/guice/SetBinderTest.java @@ -0,0 +1,33 @@ +package org.wcong.test.guice; + +import com.google.inject.AbstractModule; +import com.google.inject.Guice; +import com.google.inject.Injector; +import com.google.inject.Key; +import com.google.inject.TypeLiteral; +import com.google.inject.multibindings.Multibinder; + +import java.util.List; +import java.util.Set; + +/** + * @author wcong + * @since 2016/10/31 + */ +public class SetBinderTest { + + public static void main(String[] args) { + Injector injector = Guice.createInjector(new AbstractModule() { + @Override + protected void configure() { + Multibinder multibinder = Multibinder.newSetBinder(binder(), String.class); + multibinder.addBinding().toInstance("hello"); + multibinder.addBinding().toInstance("world"); + } + }); + Set stringList = injector.getInstance(Key.get(new TypeLiteral>() { + })); + System.out.println(stringList); + } + +} diff --git a/src/main/java/org/wcong/test/guice/TwoModuleTest.java b/src/main/java/org/wcong/test/guice/TwoModuleTest.java new file mode 100644 index 0000000..88a0f66 --- /dev/null +++ b/src/main/java/org/wcong/test/guice/TwoModuleTest.java @@ -0,0 +1,39 @@ +package org.wcong.test.guice; + +import com.google.inject.AbstractModule; +import com.google.inject.Guice; +import com.google.inject.Injector; +import com.google.inject.Singleton; + +/** + * Created by wcong on 2016/9/19. + */ +public class TwoModuleTest { + + public interface Print { + void print(); + } + + @Singleton + public static class HelloPrint implements Print { + + public void print() { + System.out.println("hello"); + } + } + + + public static void main(String[] args) { + Injector injector = Guice.createInjector(new AbstractModule() { + @Override + protected void configure() { + bind(Print.class).to(HelloPrint.class); + } + }); + Print print = injector.getInstance(Print.class); + System.out.println(print); + print = injector.getInstance(Print.class); + System.out.println(print); + } + +} diff --git a/src/main/java/org/wcong/test/hackerrank/package-info.java b/src/main/java/org/wcong/test/hackerrank/package-info.java new file mode 100644 index 0000000..93dd5ef --- /dev/null +++ b/src/main/java/org/wcong/test/hackerrank/package-info.java @@ -0,0 +1 @@ +package org.wcong.test.hackerrank; \ No newline at end of file diff --git a/src/main/java/org/wcong/test/hackerrank/string/BearAndSteadyGene.java b/src/main/java/org/wcong/test/hackerrank/string/BearAndSteadyGene.java new file mode 100644 index 0000000..8a90365 --- /dev/null +++ b/src/main/java/org/wcong/test/hackerrank/string/BearAndSteadyGene.java @@ -0,0 +1,92 @@ +package org.wcong.test.hackerrank.string; + +import java.util.HashMap; +import java.util.Map; + +/** + * given a string consist of A,C,T,G + * if each of it appear 1/4 time the length it's steady + * give a string of length n divisible of 4; + * replace a minimum substring for it make it steady + *

+ * one loop get all num if + * + * @author wcong + * @since 03/05/2017 + */ +public class BearAndSteadyGene { + + public int minimumReplace(String s) { + int expectNum = s.length() / 4; + char[] charArray = new char[] { 'A', 'C', 'T', 'G' }; + Map characterIntegerMap = new HashMap<>(); + for (char soloChar : charArray) { + characterIntegerMap.put(soloChar, 0); + } + for (int index = 0; index < s.length(); index++) { + characterIntegerMap.put(s.charAt(index), characterIntegerMap.get(s.charAt(index)) + 1); + } + for (char soloChar : charArray) { + int count = characterIntegerMap.get(soloChar); + if (count <= expectNum) { + characterIntegerMap.remove(soloChar); + } else { + characterIntegerMap.put(soloChar, count - expectNum); + } + } + if (characterIntegerMap.isEmpty()) { + return 0; + } + Map encounterMap = new HashMap<>(); + for (char soloChar : characterIntegerMap.keySet()) { + encounterMap.put(soloChar, 0); + } + + int start = 0; + int index = 0; + int minSub = Integer.MAX_VALUE; + while (!characterIntegerMap.containsKey(s.charAt(index))) { + index += 1; + start = index; + } + while (index < s.length()) { + if (characterIntegerMap.containsKey(s.charAt(index))) { + encounterMap.put(s.charAt(index), encounterMap.get(s.charAt(index)) + 1); + } + int compare = compare(characterIntegerMap, encounterMap); + if (compare == 0) { + int sub = index - start+1; + if (sub < minSub) { + minSub = sub; + } + } else if (compare > 0) { + while (start < index) { + while (!characterIntegerMap.containsKey(s.charAt(index))) { + start += 1; + } + encounterMap.put(s.charAt(index), encounterMap.get(s.charAt(index)) - 1); + if (compare(characterIntegerMap, encounterMap) < 0) { + break; + } + start+=1; + } + } + index += 1; + } + return minSub; + } + + private int compare(Map characterIntegerMap, Map encounterMap) { + boolean isEqual = true; + for (Map.Entry characterIntegerEntry : characterIntegerMap.entrySet()) { + int encounter = encounterMap.get(characterIntegerEntry.getKey()); + if (encounter > characterIntegerEntry.getValue()) { + return 1; + } else if (encounter < characterIntegerEntry.getValue()) { + isEqual = false; + } + } + return isEqual ? 0 : -1; + } + +} diff --git a/src/main/java/org/wcong/test/hackerrank/string/PerfectString.java b/src/main/java/org/wcong/test/hackerrank/string/PerfectString.java new file mode 100644 index 0000000..03e2275 --- /dev/null +++ b/src/main/java/org/wcong/test/hackerrank/string/PerfectString.java @@ -0,0 +1,64 @@ +package org.wcong.test.hackerrank.string; + +import java.util.ArrayList; +import java.util.List; + +/** + * give a string consisting of a,b,c,d + * perfect string + * 1 num of a equal num of b + * 2 num of c equal num of d + * subsequent of string + * + * @author wcong + * @since 03/05/2017 + */ +public class PerfectString { + + public long perfectNum(String originString) { + int[] count = new int[4]; + for (char soloChar : originString.toCharArray()) { + count[soloChar - 'a'] += 1; + } + long perfectNum = 0; + long abNum = 0; + int minAb = count[0] < count[1] ? count[0] : count[1]; + for (int i = 1; i <= minAb; i++) { + abNum += combination(count[0], i) * combination(count[1], i); + } + perfectNum += abNum % 1000000007; + int minCD = count[2] < count[3] ? count[2] : count[3]; + long cdNum = 0; + for (int i = 1; i <= minCD; i++) { + cdNum += combination(count[2], i) * combination(count[3], i); + } + perfectNum += cdNum % 1000000007; + perfectNum = perfectNum % 1000000007; + perfectNum += (abNum * cdNum) % 1000000007; + perfectNum = perfectNum % 1000000007; + return perfectNum; + } + + static List factorialList = new ArrayList<>(); + + static { + factorialList.add(0); + factorialList.add(1); + } + + private int combination(int total, int num) { + if (total == 0 || num == 0) { + return 0; + } + if (total == num) { + return 1; + } + if (factorialList.size() - 1 < total) { + for (int currentNum = factorialList.size(); currentNum <= total; currentNum++) { + factorialList.add(factorialList.get(currentNum - 1) * currentNum); + } + } + return factorialList.get(total) / factorialList.get(total - num) / factorialList.get(num); + } + +} diff --git a/src/main/java/org/wcong/test/javaformat/ASTParserTest.java b/src/main/java/org/wcong/test/javaformat/ASTParserTest.java new file mode 100644 index 0000000..1fa0cc3 --- /dev/null +++ b/src/main/java/org/wcong/test/javaformat/ASTParserTest.java @@ -0,0 +1,24 @@ +package org.wcong.test.javaformat; + +import org.eclipse.jdt.core.dom.AST; +import org.eclipse.jdt.core.dom.ASTParser; +import org.eclipse.jdt.core.dom.CompilationUnit; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; + +/** + * Created by wcong on 2016/11/21. + */ +public class ASTParserTest { + public static void main(String[] args) throws IOException { + ASTParser parser = ASTParser.newParser(AST.JLS8); + Path path = Paths.get("src/main/java/org/wcong/test/guice/GuiceTest.java"); + String text = new String(Files.readAllBytes(path)); + parser.setSource(text.toCharArray()); + CompilationUnit unit = (CompilationUnit) parser.createAST(null); + unit.getJavaElement(); + } +} diff --git a/src/main/java/org/wcong/test/javaformat/FormatTest.java b/src/main/java/org/wcong/test/javaformat/FormatTest.java new file mode 100644 index 0000000..becc00f --- /dev/null +++ b/src/main/java/org/wcong/test/javaformat/FormatTest.java @@ -0,0 +1,15 @@ +package org.wcong.test.javaformat; + +import com.google.googlejavaformat.java.Main; + +/** + * Created by wcong on 2016/11/17. + */ +public class FormatTest { + + public static void main(String[] args) { + String[] files = new String[1]; + files[0] = "src/main/java/org/wcong/test/guice/GuiceTest.java"; + Main.main(files); + } +} diff --git a/src/main/java/org/wcong/test/javaformat/IScannerTest.java b/src/main/java/org/wcong/test/javaformat/IScannerTest.java new file mode 100644 index 0000000..9082e93 --- /dev/null +++ b/src/main/java/org/wcong/test/javaformat/IScannerTest.java @@ -0,0 +1,31 @@ +package org.wcong.test.javaformat; + +import org.eclipse.jdt.core.ToolFactory; +import org.eclipse.jdt.core.compiler.IScanner; +import org.eclipse.jdt.core.compiler.InvalidInputException; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; + +/** + * test for IScanner + * Created by wcong on 2016/11/21. + */ +public class IScannerTest { + public static void main(String[] args) throws IOException, InvalidInputException { + IScanner scanner = ToolFactory.createScanner(true, true, true, "1.8"); + Path path = Paths.get("src/main/java/org/wcong/test/guice/GuiceTest.java"); + String text = new String(Files.readAllBytes(path)); + int textLength = text.length(); + scanner.setSource(text.toCharArray()); + while (scanner.getCurrentTokenEndPosition() < textLength - 1) { + scanner.getNextToken(); + int charI0 = scanner.getCurrentTokenStartPosition(); + // Get string, possibly with Unicode escapes. + String originalTokText = text.substring(charI0, scanner.getCurrentTokenEndPosition() + 1); + System.out.println(originalTokText); + } + } +} diff --git a/src/main/java/org/wcong/test/javaformat/RangeTest.java b/src/main/java/org/wcong/test/javaformat/RangeTest.java new file mode 100644 index 0000000..331f568 --- /dev/null +++ b/src/main/java/org/wcong/test/javaformat/RangeTest.java @@ -0,0 +1,15 @@ +package org.wcong.test.javaformat; + +import com.google.common.collect.Range; + +/** + * Created by wcong on 2016/11/21. + */ +public class RangeTest { + + public static void main(String[] args) { + Range stringRange = Range.open("a", "b"); + System.out.println(stringRange); + System.out.println(stringRange.span(Range.open("c", "d"))); + } +} diff --git a/src/main/java/org/wcong/test/mydagger/MyComponentTest.java b/src/main/java/org/wcong/test/mydagger/MyComponentTest.java new file mode 100644 index 0000000..65876da --- /dev/null +++ b/src/main/java/org/wcong/test/mydagger/MyComponentTest.java @@ -0,0 +1,11 @@ +package org.wcong.test.mydagger; + +/** + * Created by wcong on 2016/12/7. + */ +@MyComponent +public interface MyComponentTest { + + MyProvidesTest myProvidesTest(); + +} diff --git a/src/main/java/org/wcong/test/mydagger/MyProvidesTest.java b/src/main/java/org/wcong/test/mydagger/MyProvidesTest.java new file mode 100644 index 0000000..d3d10e8 --- /dev/null +++ b/src/main/java/org/wcong/test/mydagger/MyProvidesTest.java @@ -0,0 +1,17 @@ +package org.wcong.test.mydagger; + +import javax.inject.Inject; + +/** + * @author wcong + * @since 2016/12/4 + */ +@MyProvides +public class MyProvidesTest { + + @Inject + public MyProvidesTest(MyProvidesTest1 myProvidesTest1) { + + } + +} diff --git a/src/main/java/org/wcong/test/mydagger/MyProvidesTest1.java b/src/main/java/org/wcong/test/mydagger/MyProvidesTest1.java new file mode 100644 index 0000000..fbbfda8 --- /dev/null +++ b/src/main/java/org/wcong/test/mydagger/MyProvidesTest1.java @@ -0,0 +1,8 @@ +package org.wcong.test.mydagger; + +/** + * Created by wcong on 2016/12/6. + */ +@MyProvides +public class MyProvidesTest1 { +} diff --git a/src/main/java/org/wcong/test/pattern/creational/Multition.java b/src/main/java/org/wcong/test/pattern/creational/Multition.java new file mode 100644 index 0000000..97ff47b --- /dev/null +++ b/src/main/java/org/wcong/test/pattern/creational/Multition.java @@ -0,0 +1,34 @@ +package org.wcong.test.pattern.creational; + +import java.util.ArrayList; +import java.util.HashMap; + +/** + * @author wcong + * @since 2017/1/2 + */ +public class Multition { + + public static void main(String[] args){ + int[] nums = {1,3}; + System.out.println(index(0,nums.length,nums,0)); + } + + private static int index(int start,int end,int[] nums,int target){ + if( start == end ){ + if( nums[start] == target ){ + return start; + }else if( nums[start] > target ){ + return start; + }else{ + return start +1; + } + } + int middle = start + (end - start)/2; + if( nums[middle] == target ){ + return middle; + } + return index(start+1>middle?middle:start+1,end -1,nums,target); + } + +} diff --git a/src/main/java/org/wcong/test/pattern/package-info.java b/src/main/java/org/wcong/test/pattern/package-info.java new file mode 100644 index 0000000..2478af4 --- /dev/null +++ b/src/main/java/org/wcong/test/pattern/package-info.java @@ -0,0 +1,2 @@ +package org.wcong.test.pattern; +// about java pattern examples \ No newline at end of file diff --git a/src/main/java/org/wcong/test/poet/JavaFileTest.java b/src/main/java/org/wcong/test/poet/JavaFileTest.java new file mode 100644 index 0000000..2b5d1d8 --- /dev/null +++ b/src/main/java/org/wcong/test/poet/JavaFileTest.java @@ -0,0 +1,82 @@ +package org.wcong.test.poet; + +import com.squareup.javapoet.AnnotationSpec; +import com.squareup.javapoet.ClassName; +import com.squareup.javapoet.CodeBlock; +import com.squareup.javapoet.FieldSpec; +import com.squareup.javapoet.JavaFile; +import com.squareup.javapoet.MethodSpec; +import com.squareup.javapoet.ParameterSpec; +import com.squareup.javapoet.TypeName; +import com.squareup.javapoet.TypeSpec; + +import javax.lang.model.element.Modifier; +import java.util.ArrayList; +import java.util.List; + +/** + * Created by wcong on 2016/11/11. + */ +public class JavaFileTest { + public static void main(String[] args) { + TypeSpec.Builder typeSpecBuilder = TypeSpec.classBuilder("JavaFile"); + typeSpecBuilder.addAnnotation(makeAnnotationSpec()); + typeSpecBuilder.addField(makeFieldSpec()); + typeSpecBuilder.addMethods(makeMethodSpec()); + JavaFile.Builder javaFileBuilder = JavaFile.builder("org.wcong.test.poet", typeSpecBuilder.build()); + System.out.println(javaFileBuilder.build().toString()); + } + + private static AnnotationSpec makeAnnotationSpec() { + AnnotationSpec.Builder builder = AnnotationSpec.builder(ClassName.get("org.wcong.test.poet", "MyAnnotation")); + CodeBlock.Builder codeBlockBuilder = CodeBlock.builder().add("$S", "world"); + builder.addMember("hello", codeBlockBuilder.build()); + return builder.build(); + } + + private static FieldSpec makeFieldSpec() { + FieldSpec.Builder fileSpecBuilder = FieldSpec.builder(String.class, "hello", Modifier.PRIVATE); + fileSpecBuilder.initializer(CodeBlock.of("\"world\"")); + return fileSpecBuilder.build(); + } + + private static List makeMethodSpec() { + List methodSpecList = new ArrayList(); + methodSpecList.add(makeGetMethod()); + methodSpecList.add(makeSetMethod()); + methodSpecList.add(makeToStringMethod()); + return methodSpecList; + } + + private static MethodSpec makeToStringMethod() { + MethodSpec.Builder toStringBuilder = MethodSpec.methodBuilder("toString"); + toStringBuilder.addModifiers(Modifier.PUBLIC); + toStringBuilder.returns(TypeName.get(String.class)); + CodeBlock.Builder toStringCodeBuilder = CodeBlock.builder(); + toStringCodeBuilder.beginControlFlow("if( hello != null )"); + toStringCodeBuilder.add(CodeBlock.of("return \"hello \"+hello;\n")); + toStringCodeBuilder.nextControlFlow("else"); + toStringCodeBuilder.add(CodeBlock.of("return \"\";\n")); + toStringCodeBuilder.endControlFlow(); + toStringBuilder.addCode(toStringCodeBuilder.build()); + return toStringBuilder.build(); + } + + private static MethodSpec makeSetMethod() { + MethodSpec.Builder setMethodSpecBuilder = MethodSpec.methodBuilder("setHello"); + setMethodSpecBuilder.addModifiers(Modifier.PUBLIC); + setMethodSpecBuilder.returns(TypeName.VOID); + ParameterSpec.Builder parameterBuilder = ParameterSpec.builder(TypeName.get(String.class), "hello"); + setMethodSpecBuilder.addParameter(parameterBuilder.build()); + setMethodSpecBuilder.addCode(CodeBlock.builder().add("this.hello = hello;\n").build()); + return setMethodSpecBuilder.build(); + } + + private static MethodSpec makeGetMethod() { + MethodSpec.Builder getMethodSpecBuilder = MethodSpec.methodBuilder("getHello"); + getMethodSpecBuilder.addModifiers(Modifier.PUBLIC); + getMethodSpecBuilder.returns(TypeName.get(String.class)); + getMethodSpecBuilder.addCode(CodeBlock.builder().add("return hello;\n").build()); + return getMethodSpecBuilder.build(); + } +} diff --git a/src/main/java/org/wcong/test/rxjava/MyPublisher.java b/src/main/java/org/wcong/test/rxjava/MyPublisher.java new file mode 100644 index 0000000..307c6cd --- /dev/null +++ b/src/main/java/org/wcong/test/rxjava/MyPublisher.java @@ -0,0 +1,120 @@ +package org.wcong.test.rxjava; + +import io.reactivex.Flowable; +import io.reactivex.FlowableSubscriber; +import io.reactivex.Scheduler; +import io.reactivex.functions.Consumer; +import io.reactivex.schedulers.Schedulers; +import org.reactivestreams.Subscriber; +import org.reactivestreams.Subscription; + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.atomic.AtomicInteger; + +public class MyPublisher { + + private static CountDownLatch countDownLatch = new CountDownLatch(4); + + public static void main(String[] args) throws InterruptedException { + new ParallelFlowableRange(1, 100, Schedulers.computation()).subscribe(new Consumer() { + @Override + public void accept(Integer integer) throws Exception { + System.out.println(Thread.currentThread().getName() + ":" + integer); + } + }); + countDownLatch.await(); + } + + + public static class ParallelFlowableRange extends Flowable { + + private Scheduler scheduler; + + private int start; + private int end; + + public ParallelFlowableRange(int start, int end, Scheduler scheduler) { + this.scheduler = scheduler; + this.start = start; + this.end = end; + } + + @Override + protected void subscribeActual(Subscriber subscriber) { + AtomicInteger atomicInteger = new AtomicInteger(start); + for (int i = 0; i < 4; i++) { + MySubscriber mySubscriber = new MySubscriber(subscriber, Integer.MAX_VALUE, scheduler.createWorker(), atomicInteger, end); + mySubscriber.onSubscribe(mySubscriber); + } + } + } + + public static class MySubscriber extends AtomicInteger implements FlowableSubscriber, Subscription, Runnable { + + private int prefetch; + private Scheduler.Worker worker; + private Subscriber actual; + private boolean cancel; + private AtomicInteger atomicInteger; + private int end; + + public MySubscriber(Subscriber actual, int prefetch, Scheduler.Worker worker, AtomicInteger atomicInteger, int end) { + this.actual = actual; + this.prefetch = prefetch; + this.worker = worker; + this.atomicInteger = atomicInteger; + this.end = end; + } + + @Override + public void onSubscribe(Subscription subscription) { + subscription.request(prefetch); + } + + @Override + public void onNext(Integer integer) { + actual.onNext(integer); + } + + @Override + public void onError(Throwable throwable) { + actual.onError(throwable); + } + + @Override + public void onComplete() { + countDownLatch.countDown(); + actual.onComplete(); + } + + @Override + public void request(long l) { + worker.schedule(this); + } + + @Override + public void cancel() { + cancel = true; + } + + @Override + public void run() { + while (true) { + if (cancel) { + break; + } + int num = atomicInteger.getAndIncrement(); + if (num < end) { + try { + onNext(num); + } catch (Exception e) { + onError(e); + } + } else { + onComplete(); + break; + } + } + } + } +} diff --git a/src/main/java/org/wcong/test/rxjava/package-info.java b/src/main/java/org/wcong/test/rxjava/package-info.java new file mode 100644 index 0000000..7b13049 --- /dev/null +++ b/src/main/java/org/wcong/test/rxjava/package-info.java @@ -0,0 +1,3 @@ +package org.wcong.test.rxjava; + +// about rxjava \ No newline at end of file diff --git a/src/test/java/org/wcong/test/concurrent/CountDownLatchThreadTest.java b/src/test/java/org/wcong/test/concurrent/CountDownLatchThreadTest.java new file mode 100644 index 0000000..20ad1ab --- /dev/null +++ b/src/test/java/org/wcong/test/concurrent/CountDownLatchThreadTest.java @@ -0,0 +1,31 @@ +package org.wcong.test.concurrent; + +import org.junit.Test; + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; + +/** + * @author wcong + * @since 30/04/2017 + */ +public class CountDownLatchThreadTest { + + @Test + public void test() { + CountDownLatch countDownLatch = new CountDownLatch(10); + ExecutorService executorService = Executors.newFixedThreadPool(10); + for (int threadNum = 0; threadNum < 10; threadNum++) { + executorService.submit(new CountDownLatchThread(countDownLatch)); + } + executorService.shutdown(); + try { + executorService.awaitTermination(100000L, TimeUnit.MILLISECONDS); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + +} diff --git a/src/test/java/org/wcong/test/concurrent/CyclicBarrierPrintTest.java b/src/test/java/org/wcong/test/concurrent/CyclicBarrierPrintTest.java new file mode 100644 index 0000000..9f6e9d1 --- /dev/null +++ b/src/test/java/org/wcong/test/concurrent/CyclicBarrierPrintTest.java @@ -0,0 +1,41 @@ +package org.wcong.test.concurrent; + +import org.junit.Test; + +import java.util.concurrent.CyclicBarrier; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; + +/** + * @author wcong + * @since 30/04/2017 + */ +public class CyclicBarrierPrintTest { + + public static class CyclicBarrierMonitor implements Runnable { + + private int stage; + + @Override + public void run() { + System.out.println("we all are ready for stage :" + stage++); + } + } + + @Test + public void test() { + CyclicBarrier cyclicBarrier = new CyclicBarrier(10, new CyclicBarrierMonitor()); + ExecutorService executorService = Executors.newFixedThreadPool(10); + for (int threadNum = 0; threadNum < 10; threadNum++) { + executorService.submit(new CyclicBarrierPrint(cyclicBarrier)); + } + executorService.shutdown(); + try { + executorService.awaitTermination(10000L, TimeUnit.MILLISECONDS); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + +} diff --git a/src/test/java/org/wcong/test/concurrent/PhaserPrintTest.java b/src/test/java/org/wcong/test/concurrent/PhaserPrintTest.java new file mode 100644 index 0000000..e716615 --- /dev/null +++ b/src/test/java/org/wcong/test/concurrent/PhaserPrintTest.java @@ -0,0 +1,31 @@ +package org.wcong.test.concurrent; + +import org.junit.Test; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Phaser; +import java.util.concurrent.TimeUnit; + +/** + * @author wcong + * @since 30/04/2017 + */ +public class PhaserPrintTest { + + @Test + public void test() { + final Phaser phaser = new Phaser(10); // this will add to 10 emedialy,do not register again; + ExecutorService executorService = Executors.newFixedThreadPool(10); + for (int threadNum = 0; threadNum < 10; threadNum++) { + executorService.submit(new PhaserPrint(phaser)); + } + executorService.shutdown(); + try { + executorService.awaitTermination(10000L, TimeUnit.MILLISECONDS); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + +} diff --git a/src/test/java/org/wcong/test/concurrent/SemaphorePrintTest.java b/src/test/java/org/wcong/test/concurrent/SemaphorePrintTest.java new file mode 100644 index 0000000..2dbd7b2 --- /dev/null +++ b/src/test/java/org/wcong/test/concurrent/SemaphorePrintTest.java @@ -0,0 +1,44 @@ +package org.wcong.test.concurrent; + +import org.junit.Test; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; + +/** + * @author wcong + * @since 30/04/2017 + */ +public class SemaphorePrintTest { + + static class PrintRunner implements Runnable { + + private SemaphorePrint semaphorePrint; + + public PrintRunner(SemaphorePrint semaphorePrint) { + this.semaphorePrint = semaphorePrint; + } + + @Override + public void run() { + semaphorePrint.print(); + } + } + + @Test + public void test() { + SemaphorePrint semaphorePrint = new SemaphorePrint(); + ExecutorService executor = Executors.newFixedThreadPool(10); + for (int threadNum = 0; threadNum < 10; threadNum++) { + executor.submit(new PrintRunner(semaphorePrint)); + } + executor.shutdown(); + try { + executor.awaitTermination(10000L, TimeUnit.MILLISECONDS); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + +} diff --git a/src/test/java/org/wcong/test/concurrent/SynchronizedMethodTest.java b/src/test/java/org/wcong/test/concurrent/SynchronizedMethodTest.java new file mode 100644 index 0000000..6e16b98 --- /dev/null +++ b/src/test/java/org/wcong/test/concurrent/SynchronizedMethodTest.java @@ -0,0 +1,26 @@ +package org.wcong.test.concurrent; + +import org.junit.Test; + +/** + * @author wcong + * @since 30/04/2017 + */ +public class SynchronizedMethodTest { + + @Test + public void test() { + SynchronizedMethod synchronizedMethod = new SynchronizedMethod(); + SynchronizedMethod.MyPutThread myPutThread = new SynchronizedMethod.MyPutThread(synchronizedMethod); + myPutThread.start(); + SynchronizedMethod.MyGetThread myGetThread = new SynchronizedMethod.MyGetThread(synchronizedMethod); + myGetThread.start(); + try { + myGetThread.join(); + myPutThread.join(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + +} diff --git a/src/test/java/org/wcong/test/concurrent/ThreadWithStopTest.java b/src/test/java/org/wcong/test/concurrent/ThreadWithStopTest.java new file mode 100644 index 0000000..505e772 --- /dev/null +++ b/src/test/java/org/wcong/test/concurrent/ThreadWithStopTest.java @@ -0,0 +1,31 @@ +package org.wcong.test.concurrent; + +import org.junit.Test; + +import java.util.concurrent.TimeUnit; + +/** + * @author wcong + * @since 30/04/2017 + */ +public class ThreadWithStopTest { + + @Test + public void testStop() { + ThreadWithStop thread = new ThreadWithStop(); + thread.start(); + try { + TimeUnit.MILLISECONDS.sleep(5000L); + } catch (InterruptedException e) { + e.printStackTrace(); + } + System.out.println("i will set you stop"); + thread.setStop(true); + try { + thread.join(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + +} diff --git a/src/test/java/org/wcong/test/hackerrank/package-info.java b/src/test/java/org/wcong/test/hackerrank/package-info.java new file mode 100644 index 0000000..93dd5ef --- /dev/null +++ b/src/test/java/org/wcong/test/hackerrank/package-info.java @@ -0,0 +1 @@ +package org.wcong.test.hackerrank; \ No newline at end of file diff --git a/src/test/java/org/wcong/test/hackerrank/string/BearAndSteadyGeneTest.java b/src/test/java/org/wcong/test/hackerrank/string/BearAndSteadyGeneTest.java new file mode 100644 index 0000000..8298e58 --- /dev/null +++ b/src/test/java/org/wcong/test/hackerrank/string/BearAndSteadyGeneTest.java @@ -0,0 +1,19 @@ +package org.wcong.test.hackerrank.string; + +import org.eclipse.core.runtime.Assert; +import org.junit.Test; + +/** + * @author wcong + * @since 04/05/2017 + */ +public class BearAndSteadyGeneTest { + + @Test + public void test() { + BearAndSteadyGene bearAndSteadyGene = new BearAndSteadyGene(); + Assert.isTrue(bearAndSteadyGene.minimumReplace("GAAATAAA") == 5); + + } + +} diff --git a/src/test/java/org/wcong/test/hackerrank/string/PerfectStringTest.java b/src/test/java/org/wcong/test/hackerrank/string/PerfectStringTest.java new file mode 100644 index 0000000..dab4d53 --- /dev/null +++ b/src/test/java/org/wcong/test/hackerrank/string/PerfectStringTest.java @@ -0,0 +1,21 @@ +package org.wcong.test.hackerrank.string; + +import org.eclipse.core.runtime.Assert; +import org.junit.Test; + +/** + * @author wcong + * @since 03/05/2017 + */ +public class PerfectStringTest { + + @Test + public void test() { + PerfectString perfectString = new PerfectString(); + Assert.isTrue(perfectString.perfectNum("abcd") == 3); + Assert.isTrue(perfectString.perfectNum("abc") == 1); + Assert.isTrue(perfectString.perfectNum("ddc") == 2); + Assert.isTrue(perfectString.perfectNum("dddccc") == 19); + } + +} diff --git a/src/test/java/org/wcong/test/leetcode/NumberToWordsTest.java b/src/test/java/org/wcong/test/leetcode/NumberToWordsTest.java new file mode 100644 index 0000000..f8c0f8b --- /dev/null +++ b/src/test/java/org/wcong/test/leetcode/NumberToWordsTest.java @@ -0,0 +1,22 @@ +package org.wcong.test.leetcode; + +import org.junit.Assert; +import org.junit.Test; +import org.wcong.test.algorithm.leetcode.numbers.NumberToWords; + +/** + * @author wcong + * @since 16/05/2017 + */ +public class NumberToWordsTest { + + @Test + public void testNumberToWords() { + NumberToWords numberToWords = new NumberToWords(); + Assert.assertTrue(numberToWords.numberToWords(123).equals("One Hundred Twenty Three")); + Assert.assertTrue(numberToWords.numberToWords(12345).equals("Twelve Thousand Three Hundred Forty Five")); + Assert.assertTrue(numberToWords.numberToWords(1234567) + .equals("One Million Two Hundred Thirty Four Thousand Five Hundred Sixty Seven")); + } + +} diff --git a/src/test/java/org/wcong/test/leetcode/array/BestTimeBuySellStockIVTest.java b/src/test/java/org/wcong/test/leetcode/array/BestTimeBuySellStockIVTest.java new file mode 100644 index 0000000..c66f40f --- /dev/null +++ b/src/test/java/org/wcong/test/leetcode/array/BestTimeBuySellStockIVTest.java @@ -0,0 +1,28 @@ +package org.wcong.test.leetcode.array; + +import org.junit.Assert; +import org.junit.Test; +import org.wcong.test.algorithm.leetcode.string.BestTimeBuySellStockIV; + +/** + * @author wcong + * @since 10/06/2017 + */ +public class BestTimeBuySellStockIVTest { + + @Test + public void testMaxProfit() { + BestTimeBuySellStockIV solution = new BestTimeBuySellStockIV(); + int[] simple = new int[]{0, 1}; + int[] oneMax = new int[]{0, 1, 2, 3, 4, 5, 6, 7, 8}; + int[] transaction = new int[]{1, 2}; + int[] time = new int[]{48, 12, 60, 93, 97, 42, 25, 64, 17, 56, 85, 93, 9, 48, 52, 42, 58, 85, 81, 84, 69, 36, 1, 54, 23, 15, 72, 15, 11, 94}; + int[] border = new int[]{1, 4, 2}; + Assert.assertTrue(solution.maxProfitDp(2, simple) == 1); + Assert.assertTrue(solution.maxProfitDp(9, oneMax) == 8); + Assert.assertTrue(solution.maxProfitDp(1, transaction) == 1); + Assert.assertTrue(solution.maxProfitDp(2, border) == 3); + } + + +} diff --git a/src/test/java/org/wcong/test/leetcode/array/CandyTest.java b/src/test/java/org/wcong/test/leetcode/array/CandyTest.java new file mode 100644 index 0000000..8d8b4a6 --- /dev/null +++ b/src/test/java/org/wcong/test/leetcode/array/CandyTest.java @@ -0,0 +1,23 @@ +package org.wcong.test.leetcode.array; + +import org.junit.Assert; +import org.junit.Test; +import org.wcong.test.algorithm.leetcode.array.Candy; + +/** + * @author wcong + * @since 19/06/2017 + */ +public class CandyTest { + + @Test + public void testCandies() { + Candy candy = new Candy(); + Assert.assertTrue(candy.candy(new int[]{11111}) == 1); + Assert.assertTrue(candy.candy(new int[]{1, 2, 2}) == 4); + Assert.assertTrue(candy.candy(new int[]{5, 4, 3, 2, 1, 0}) == 21); + Assert.assertTrue(candy.candy(new int[]{5, 4, 4, 2, 1, 0}) == 13); + Assert.assertTrue(candy.candy(new int[]{4, 2, 3, 4, 1}) == 9); + } + +} diff --git a/src/test/java/org/wcong/test/leetcode/array/CreateMaximumNumberTest.java b/src/test/java/org/wcong/test/leetcode/array/CreateMaximumNumberTest.java new file mode 100644 index 0000000..ff9720e --- /dev/null +++ b/src/test/java/org/wcong/test/leetcode/array/CreateMaximumNumberTest.java @@ -0,0 +1,38 @@ +package org.wcong.test.leetcode.array; + +import org.junit.Assert; +import org.junit.Test; +import org.wcong.test.algorithm.leetcode.array.CreateMaximumNumber; + +import java.util.Arrays; + +/** + * @author wcong + * @since 13/06/2017 + */ +public class CreateMaximumNumberTest { + + @Test + public void testMaxNumber() { + + CreateMaximumNumber solution = new CreateMaximumNumber(); + int[] e3nums1 = new int[]{3, 9}; + int[] e3nums2 = new int[]{8, 9}; + int[] e3result = new int[]{9, 8, 9}; + Assert.assertTrue(Arrays.equals(solution.maxNumberGreed(e3nums1, e3nums2, 3), e3result)); + int[] e1nums1 = new int[]{3, 4, 6, 5}; + int[] e1nums2 = new int[]{9, 1, 2, 5, 8, 3}; + int[] e1result = new int[]{9, 8, 6, 5, 3}; + Assert.assertTrue(Arrays.equals(solution.maxNumberGreed(e1nums1, e1nums2, 5), e1result)); + int[] e2nums1 = new int[]{6, 7}; + int[] e2nums2 = new int[]{6, 0, 4}; + int[] e2result = new int[]{6, 7, 6, 0, 4}; + Assert.assertTrue(Arrays.equals(solution.maxNumberGreed(e2nums1, e2nums2, 5), e2result)); + try { + throw new NoClassDefFoundError(); + } catch (Error e) { + e.printStackTrace(); + } + } + +} diff --git a/src/test/java/org/wcong/test/leetcode/array/MaxPointsOnALineTest.java b/src/test/java/org/wcong/test/leetcode/array/MaxPointsOnALineTest.java new file mode 100644 index 0000000..4d760e2 --- /dev/null +++ b/src/test/java/org/wcong/test/leetcode/array/MaxPointsOnALineTest.java @@ -0,0 +1,33 @@ +package org.wcong.test.leetcode.array; + +import org.junit.Assert; +import org.junit.Test; +import org.wcong.test.algorithm.leetcode.array.MaxPointsOnALine; + +/** + * @author wcong + * @since 10/05/2017 + */ +public class MaxPointsOnALineTest { + + @Test + public void testMaxPoints() { + MaxPointsOnALine maxPointsOnALine = new MaxPointsOnALine(); + MaxPointsOnALine.Point[] points = new MaxPointsOnALine.Point[] { new MaxPointsOnALine.Point(0, 0), + new MaxPointsOnALine.Point(1, 1), new MaxPointsOnALine.Point(2, 2), new MaxPointsOnALine.Point(1, 0), + new MaxPointsOnALine.Point(2, 0) }; + MaxPointsOnALine.Point[] points1 = new MaxPointsOnALine.Point[] { new MaxPointsOnALine.Point(0, 0), + new MaxPointsOnALine.Point(1, 1), new MaxPointsOnALine.Point(0, 0) }; + MaxPointsOnALine.Point[] points2 = new MaxPointsOnALine.Point[] { new MaxPointsOnALine.Point(1, 1),new MaxPointsOnALine.Point(1, 1), + new MaxPointsOnALine.Point(2, 2) , new MaxPointsOnALine.Point(2, 2) }; + //[-4,1],[-7,7],[-1,5],[9,-25] + MaxPointsOnALine.Point[] points3 = new MaxPointsOnALine.Point[] { new MaxPointsOnALine.Point(-4, 1),new MaxPointsOnALine.Point(-7, 7), + new MaxPointsOnALine.Point(-1, 5) , new MaxPointsOnALine.Point(9, -25) }; + Assert.assertTrue(maxPointsOnALine.maxPointsBruteForce(points) == 3); + Assert.assertTrue(maxPointsOnALine.maxPointsDp(points) == 3); + Assert.assertTrue(maxPointsOnALine.maxPointsDp(points1) == 3); + Assert.assertTrue(maxPointsOnALine.maxPointsDp(points2) == 4); + Assert.assertTrue(maxPointsOnALine.maxPointsDp(points3) == 3); + } + +} diff --git a/src/test/java/org/wcong/test/leetcode/array/MedianOfTwoSortedArrayTest.java b/src/test/java/org/wcong/test/leetcode/array/MedianOfTwoSortedArrayTest.java new file mode 100644 index 0000000..83a2cb5 --- /dev/null +++ b/src/test/java/org/wcong/test/leetcode/array/MedianOfTwoSortedArrayTest.java @@ -0,0 +1,20 @@ +package org.wcong.test.leetcode.array; + +import org.junit.Assert; +import org.junit.Test; +import org.wcong.test.algorithm.leetcode.array.MedianOfTwoSortedArray; + +/** + * @author wcong + * @since 11/05/2017 + */ +public class MedianOfTwoSortedArrayTest { + + @Test + public void testFindMedianSortedArrays() { + MedianOfTwoSortedArray medianOfTwoSortedArray = new MedianOfTwoSortedArray(); + Assert.assertTrue(medianOfTwoSortedArray.findMedianSortedArrays(new int[] { 1, 3 }, new int[] { 2 }) == 2); + Assert.assertTrue(medianOfTwoSortedArray.findMedianSortedArrays(new int[] { 1, 3 }, new int[] { 3, 4 }) == 2.5); + } + +} diff --git a/src/test/java/org/wcong/test/leetcode/array/NUmbersOfIslandsTest.java b/src/test/java/org/wcong/test/leetcode/array/NUmbersOfIslandsTest.java new file mode 100644 index 0000000..4a60777 --- /dev/null +++ b/src/test/java/org/wcong/test/leetcode/array/NUmbersOfIslandsTest.java @@ -0,0 +1,24 @@ +package org.wcong.test.leetcode.array; + +import org.junit.Assert; +import org.junit.Test; +import org.wcong.test.algorithm.leetcode.array.NumbersOfIslands; + +/** + * @author wcong + * @since 09/05/2017 + */ +public class NUmbersOfIslandsTest { + + @Test + public void testNumIslandsBruteForce() { + NumbersOfIslands numbersOfIslands = new NumbersOfIslands(); + char[][] chars1 = new char[][] { "11110".toCharArray(), "11010".toCharArray(), "11000".toCharArray(), + "00000".toCharArray() }; + Assert.assertTrue(numbersOfIslands.numIslandsBruteForce(chars1) == 1); + char[][] chars2 = new char[][] { "11000".toCharArray(), "11000".toCharArray(), "00100".toCharArray(), + "00011".toCharArray() }; + Assert.assertTrue(numbersOfIslands.numIslandsBruteForce(chars2) == 3); + } + +} diff --git a/src/test/java/org/wcong/test/leetcode/package-info.java b/src/test/java/org/wcong/test/leetcode/package-info.java new file mode 100644 index 0000000..6c0fd94 --- /dev/null +++ b/src/test/java/org/wcong/test/leetcode/package-info.java @@ -0,0 +1 @@ +package org.wcong.test.leetcode; \ No newline at end of file diff --git a/src/test/java/org/wcong/test/leetcode/string/InterleavingStringTest.java b/src/test/java/org/wcong/test/leetcode/string/InterleavingStringTest.java new file mode 100644 index 0000000..245ba95 --- /dev/null +++ b/src/test/java/org/wcong/test/leetcode/string/InterleavingStringTest.java @@ -0,0 +1,24 @@ +package org.wcong.test.leetcode.string; + +import org.junit.Assert; +import org.junit.Test; +import org.wcong.test.algorithm.leetcode.string.InterleavingString; + +/** + * @author wcong + * @since 15/06/2017 + */ +public class InterleavingStringTest { + + @Test + public void testIsInterleave() { + String s1 = "aabcc"; + String s2 = "dbbca"; + String s3 = "aadbbcbcac"; + String s4 = "aadbbbaccc"; + InterleavingString solution = new InterleavingString(); + Assert.assertTrue(solution.isInterleaveBruteForce(s1, s2, s3)); + Assert.assertTrue(!solution.isInterleaveBruteForce(s1, s2, s4)); + } + +} diff --git a/src/test/java/org/wcong/test/leetcode/string/KthSmallestLexicographicalOrderTest.java b/src/test/java/org/wcong/test/leetcode/string/KthSmallestLexicographicalOrderTest.java new file mode 100644 index 0000000..55b26c3 --- /dev/null +++ b/src/test/java/org/wcong/test/leetcode/string/KthSmallestLexicographicalOrderTest.java @@ -0,0 +1,24 @@ +package org.wcong.test.leetcode.string; + +import org.junit.Assert; +import org.junit.Test; +import org.wcong.test.algorithm.leetcode.string.KthSmallestLexicographicalOrder; + +/** + * @author wcong + * @since 06/06/2017 + */ +public class KthSmallestLexicographicalOrderTest { + + + @Test + public void testFindKthNumber() { + KthSmallestLexicographicalOrder solution = new KthSmallestLexicographicalOrder(); + Assert.assertTrue(solution.findKthNumberBruteForce(13, 2) == 10); + Assert.assertTrue(solution.findKthNumberGreed(13, 2) == 10); + Assert.assertTrue(solution.findKthNumberGreed(132, 4) == 101); + Assert.assertTrue(solution.findKthNumberGreed(10, 3) == 2); + Assert.assertTrue(solution.findKthNumberGreed(1000, 1000) == 9999); + } + +} diff --git a/src/test/java/org/wcong/test/leetcode/string/LongestValidParenthesesTest.java b/src/test/java/org/wcong/test/leetcode/string/LongestValidParenthesesTest.java new file mode 100644 index 0000000..5aa3e6c --- /dev/null +++ b/src/test/java/org/wcong/test/leetcode/string/LongestValidParenthesesTest.java @@ -0,0 +1,31 @@ +package org.wcong.test.leetcode.string; + +import org.junit.Assert; +import org.junit.Test; +import org.wcong.test.algorithm.leetcode.string.LongestValidParentheses; + +/** + * @author wcong + * @since 03/06/2017 + */ +public class LongestValidParenthesesTest { + + @Test + public void testLongestValidParentheses() { + String s1 = "(()"; + String s2 = ")()())"; + String s3 = ")()()))()()()(())"; + String s4 = "()(()"; + String s5 = "(()(((()"; + LongestValidParentheses solution = new LongestValidParentheses(); + Assert.assertTrue(solution.longestValidParenthesesBruteForce(s1) == 2); + Assert.assertTrue(solution.longestValidParenthesesBruteForce(s2) == 4); + Assert.assertTrue(solution.longestValidParenthesesBruteForce(s3) == 10); + Assert.assertTrue(solution.longestValidParenthesesGreed(s1) == 2); + Assert.assertTrue(solution.longestValidParenthesesGreed(s2) == 4); + Assert.assertTrue(solution.longestValidParenthesesGreed(s3) == 10); + Assert.assertTrue(solution.longestValidParenthesesGreed(s4) == 2); + Assert.assertTrue(solution.longestValidParenthesesGreed(s5) == 2); + } + +} diff --git a/src/test/java/org/wcong/test/leetcode/string/PalindromePartitioning2Test.java b/src/test/java/org/wcong/test/leetcode/string/PalindromePartitioning2Test.java new file mode 100644 index 0000000..e24a894 --- /dev/null +++ b/src/test/java/org/wcong/test/leetcode/string/PalindromePartitioning2Test.java @@ -0,0 +1,21 @@ +package org.wcong.test.leetcode.string; + +import org.junit.Assert; +import org.junit.Test; +import org.wcong.test.algorithm.leetcode.string.PalindromePartitioning2; + +/** + * @author wcong + * @since 07/06/2017 + */ +public class PalindromePartitioning2Test { + + @Test + public void testMinCutBruteForceDp() { + PalindromePartitioning2 solution = new PalindromePartitioning2(); + Assert.assertTrue(solution.minCutDp("aab") == 1); + Assert.assertTrue(solution.minCutDp("daa") == 1); + Assert.assertTrue(solution.minCutDp("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") == 1); + } + +} diff --git a/src/test/java/org/wcong/test/leetcode/string/ReversePiarsTest.java b/src/test/java/org/wcong/test/leetcode/string/ReversePiarsTest.java new file mode 100644 index 0000000..1d2cf36 --- /dev/null +++ b/src/test/java/org/wcong/test/leetcode/string/ReversePiarsTest.java @@ -0,0 +1,25 @@ +package org.wcong.test.leetcode.string; + +import org.junit.Assert; +import org.junit.Test; +import org.wcong.test.algorithm.leetcode.array.ReversePairs; + +/** + * @author wcong + * @since 04/05/2017 + */ +public class ReversePiarsTest { + + @Test + public void test() { + int[] nums = new int[] { 1, 3, 4, 6, 8, 2 }; + int[] maxInt = new int[] { 2147483647, 2147483647, 2147483647, 2147483647, 2147483647, 2147483647 }; + ReversePairs reversePairs = new ReversePairs(); + Assert.assertTrue(reversePairs.reversePairsBruteForce(nums) == 2); + Assert.assertTrue(reversePairs.reversePairsDivideAndConquer(nums) == 2); + Assert.assertTrue(reversePairs.reversePairsDivideAndConquer(maxInt) == 0); + Assert.assertTrue(reversePairs.reversePairsLiner(new int[] { 1, 3, 4, 6, 8, 2 }) == 2); + Assert.assertTrue(reversePairs.reversePairsLiner(maxInt) == 0); + } + +} diff --git a/src/test/java/org/wcong/test/leetcode/string/ShortestPalindromeTest.java b/src/test/java/org/wcong/test/leetcode/string/ShortestPalindromeTest.java new file mode 100644 index 0000000..339a190 --- /dev/null +++ b/src/test/java/org/wcong/test/leetcode/string/ShortestPalindromeTest.java @@ -0,0 +1,20 @@ +package org.wcong.test.leetcode.string; + +import org.junit.Assert; +import org.junit.Test; +import org.wcong.test.algorithm.leetcode.string.ShortestPalindrome; + +/** + * @author wcong + * @since 07/06/2017 + */ +public class ShortestPalindromeTest { + + @Test + public void testShortestPalindrome() { + ShortestPalindrome solution = new ShortestPalindrome(); + Assert.assertTrue(solution.shortestPalindromeBruteForce("aacecaaa").equals("aaacecaaa")); + Assert.assertTrue(solution.shortestPalindromeBruteForce("abcd").equals("dcbabcd")); + } + +} diff --git a/src/test/java/org/wcong/test/leetcode/string/SubstringWithConcatenationAllWordsTest.java b/src/test/java/org/wcong/test/leetcode/string/SubstringWithConcatenationAllWordsTest.java new file mode 100644 index 0000000..9919d80 --- /dev/null +++ b/src/test/java/org/wcong/test/leetcode/string/SubstringWithConcatenationAllWordsTest.java @@ -0,0 +1,23 @@ +package org.wcong.test.leetcode.string; + +import org.junit.Assert; +import org.junit.Test; +import org.wcong.test.algorithm.leetcode.string.SubstringWithConcatenationAllWords; + +import java.util.Arrays; + +/** + * @author wcong + * @since 17/05/2017 + */ +public class SubstringWithConcatenationAllWordsTest { + + @Test + public void testFindSubstring() { + SubstringWithConcatenationAllWords test = new SubstringWithConcatenationAllWords(); + Assert.assertTrue(test.findSubstringBruteForce("barfoothefoobarman", new String[] { "foo", "bar" }) + .containsAll(Arrays.asList(0, 9))); + + } + +} diff --git a/src/test/java/org/wcong/test/leetcode/string/WordBreak2Test.java b/src/test/java/org/wcong/test/leetcode/string/WordBreak2Test.java new file mode 100644 index 0000000..90b0bbe --- /dev/null +++ b/src/test/java/org/wcong/test/leetcode/string/WordBreak2Test.java @@ -0,0 +1,31 @@ +package org.wcong.test.leetcode.string; + +import org.junit.Assert; +import org.junit.Test; +import org.wcong.test.algorithm.leetcode.string.WordBreak2; + +import java.util.Arrays; +import java.util.List; + +/** + * @author wcong + * @since 24/05/2017 + */ +public class WordBreak2Test { + + @Test + public void testWordBreak2() { + List dict = Arrays.asList("cat", "cats", "and", "sand", "dog"); + WordBreak2 wordBreak2 = new WordBreak2(); + List result = wordBreak2.wordBreakBruteForce("catsanddog", dict); + Assert.assertTrue(result.get(0).equals("cat sand dog")); + Assert.assertTrue(result.get(1).equals("cats and dog")); + List resultDp = wordBreak2.wordBreakDp("catsanddog", dict); + Assert.assertTrue(resultDp.get(1).equals("cat sand dog")); + Assert.assertTrue(resultDp.get(0).equals("cats and dog")); + List dictNone = Arrays.asList("aaaa", "aa"); + List resultDpNone = wordBreak2.wordBreakDp("aaaaaaa", dictNone); + Assert.assertTrue(resultDpNone.isEmpty()); + } + +} diff --git a/src/test/java/org/wcong/test/leetcode/string/WordSearch2Test.java b/src/test/java/org/wcong/test/leetcode/string/WordSearch2Test.java new file mode 100644 index 0000000..7db6321 --- /dev/null +++ b/src/test/java/org/wcong/test/leetcode/string/WordSearch2Test.java @@ -0,0 +1,27 @@ +package org.wcong.test.leetcode.string; + +import org.junit.Assert; +import org.junit.Test; +import org.wcong.test.algorithm.leetcode.string.WordSearch2; + +import java.util.List; + +/** + * @author wcong + * @since 26/05/2017 + */ +public class WordSearch2Test { + + @Test + public void testWordSearch2() { + char[][] board = new char[][]{{'o', 'a', 'a', 'n'}, + {'e', 't', 'a', 'e'}, + {'i', 'h', 'k', 'r'}, + {'i', 'f', 'l', 'v'}}; + WordSearch2 wordSearch2 = new WordSearch2(); + List result = wordSearch2.findWords(board, new String[]{"oath", "pea", "eat", "rain"}); + Assert.assertTrue(result.get(0).equals("oath")); + Assert.assertTrue(result.get(1).equals("eat")); + } + +} diff --git a/src/test/java/org/wcong/test/leetcode/tree/BinaryTreeMaximumSubPathTest.java b/src/test/java/org/wcong/test/leetcode/tree/BinaryTreeMaximumSubPathTest.java new file mode 100644 index 0000000..ba5836a --- /dev/null +++ b/src/test/java/org/wcong/test/leetcode/tree/BinaryTreeMaximumSubPathTest.java @@ -0,0 +1,28 @@ +package org.wcong.test.leetcode.tree; + +import org.junit.Assert; +import org.junit.Test; +import org.wcong.test.algorithm.leetcode.tree.BinaryTreeMaximumSubPath; +import org.wcong.test.algorithm.leetcode.tree.TreeNode; + +/** + * @author wcong + * @since 05/05/2017 + */ +public class BinaryTreeMaximumSubPathTest { + + @Test + public void test() { + BinaryTreeMaximumSubPath maximumSubPath = new BinaryTreeMaximumSubPath(); + TreeNode treeNode = new TreeNode(); + treeNode.val = 1; + TreeNode left = new TreeNode(); + left.val = 2; + treeNode.left = left; + TreeNode right = new TreeNode(); + right.val = 3; + treeNode.right = right; + Assert.assertTrue(maximumSubPath.maxPathSum(treeNode) == 6); + } + +} diff --git a/src/test/java/org/wcong/test/package-info.java b/src/test/java/org/wcong/test/package-info.java new file mode 100644 index 0000000..45f186d --- /dev/null +++ b/src/test/java/org/wcong/test/package-info.java @@ -0,0 +1 @@ +package org.wcong.test; \ No newline at end of file