backup
|
@ -0,0 +1,33 @@
|
|||
HELP.md
|
||||
target/
|
||||
!.mvn/wrapper/maven-wrapper.jar
|
||||
!**/src/main/**/target/
|
||||
!**/src/test/**/target/
|
||||
|
||||
### STS ###
|
||||
.apt_generated
|
||||
.classpath
|
||||
.factorypath
|
||||
.project
|
||||
.settings
|
||||
.springBeans
|
||||
.sts4-cache
|
||||
|
||||
### IntelliJ IDEA ###
|
||||
.idea
|
||||
*.iws
|
||||
*.iml
|
||||
*.ipr
|
||||
|
||||
### NetBeans ###
|
||||
/nbproject/private/
|
||||
/nbbuild/
|
||||
/dist/
|
||||
/nbdist/
|
||||
/.nb-gradle/
|
||||
build/
|
||||
!**/src/main/**/build/
|
||||
!**/src/test/**/build/
|
||||
|
||||
### VS Code ###
|
||||
.vscode/
|
|
@ -0,0 +1,2 @@
|
|||
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.4/apache-maven-3.8.4-bin.zip
|
||||
wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar
|
|
@ -0,0 +1,316 @@
|
|||
#!/bin/sh
|
||||
# ----------------------------------------------------------------------------
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# Maven Start Up Batch script
|
||||
#
|
||||
# Required ENV vars:
|
||||
# ------------------
|
||||
# JAVA_HOME - location of a JDK home dir
|
||||
#
|
||||
# Optional ENV vars
|
||||
# -----------------
|
||||
# M2_HOME - location of maven2's installed home dir
|
||||
# MAVEN_OPTS - parameters passed to the Java VM when running Maven
|
||||
# e.g. to debug Maven itself, use
|
||||
# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
|
||||
# MAVEN_SKIP_RC - flag to disable loading of mavenrc files
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
if [ -z "$MAVEN_SKIP_RC" ] ; then
|
||||
|
||||
if [ -f /usr/local/etc/mavenrc ] ; then
|
||||
. /usr/local/etc/mavenrc
|
||||
fi
|
||||
|
||||
if [ -f /etc/mavenrc ] ; then
|
||||
. /etc/mavenrc
|
||||
fi
|
||||
|
||||
if [ -f "$HOME/.mavenrc" ] ; then
|
||||
. "$HOME/.mavenrc"
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
# OS specific support. $var _must_ be set to either true or false.
|
||||
cygwin=false;
|
||||
darwin=false;
|
||||
mingw=false
|
||||
case "`uname`" in
|
||||
CYGWIN*) cygwin=true ;;
|
||||
MINGW*) mingw=true;;
|
||||
Darwin*) darwin=true
|
||||
# Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
|
||||
# See https://developer.apple.com/library/mac/qa/qa1170/_index.html
|
||||
if [ -z "$JAVA_HOME" ]; then
|
||||
if [ -x "/usr/libexec/java_home" ]; then
|
||||
export JAVA_HOME="`/usr/libexec/java_home`"
|
||||
else
|
||||
export JAVA_HOME="/Library/Java/Home"
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ -z "$JAVA_HOME" ] ; then
|
||||
if [ -r /etc/gentoo-release ] ; then
|
||||
JAVA_HOME=`java-config --jre-home`
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -z "$M2_HOME" ] ; then
|
||||
## resolve links - $0 may be a link to maven's home
|
||||
PRG="$0"
|
||||
|
||||
# need this for relative symlinks
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG="`dirname "$PRG"`/$link"
|
||||
fi
|
||||
done
|
||||
|
||||
saveddir=`pwd`
|
||||
|
||||
M2_HOME=`dirname "$PRG"`/..
|
||||
|
||||
# make it fully qualified
|
||||
M2_HOME=`cd "$M2_HOME" && pwd`
|
||||
|
||||
cd "$saveddir"
|
||||
# echo Using m2 at $M2_HOME
|
||||
fi
|
||||
|
||||
# For Cygwin, ensure paths are in UNIX format before anything is touched
|
||||
if $cygwin ; then
|
||||
[ -n "$M2_HOME" ] &&
|
||||
M2_HOME=`cygpath --unix "$M2_HOME"`
|
||||
[ -n "$JAVA_HOME" ] &&
|
||||
JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
|
||||
[ -n "$CLASSPATH" ] &&
|
||||
CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
|
||||
fi
|
||||
|
||||
# For Mingw, ensure paths are in UNIX format before anything is touched
|
||||
if $mingw ; then
|
||||
[ -n "$M2_HOME" ] &&
|
||||
M2_HOME="`(cd "$M2_HOME"; pwd)`"
|
||||
[ -n "$JAVA_HOME" ] &&
|
||||
JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
|
||||
fi
|
||||
|
||||
if [ -z "$JAVA_HOME" ]; then
|
||||
javaExecutable="`which javac`"
|
||||
if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
|
||||
# readlink(1) is not available as standard on Solaris 10.
|
||||
readLink=`which readlink`
|
||||
if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
|
||||
if $darwin ; then
|
||||
javaHome="`dirname \"$javaExecutable\"`"
|
||||
javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
|
||||
else
|
||||
javaExecutable="`readlink -f \"$javaExecutable\"`"
|
||||
fi
|
||||
javaHome="`dirname \"$javaExecutable\"`"
|
||||
javaHome=`expr "$javaHome" : '\(.*\)/bin'`
|
||||
JAVA_HOME="$javaHome"
|
||||
export JAVA_HOME
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -z "$JAVACMD" ] ; then
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
fi
|
||||
else
|
||||
JAVACMD="`\\unset -f command; \\command -v java`"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
echo "Error: JAVA_HOME is not defined correctly." >&2
|
||||
echo " We cannot execute $JAVACMD" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$JAVA_HOME" ] ; then
|
||||
echo "Warning: JAVA_HOME environment variable is not set."
|
||||
fi
|
||||
|
||||
CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
|
||||
|
||||
# traverses directory structure from process work directory to filesystem root
|
||||
# first directory with .mvn subdirectory is considered project base directory
|
||||
find_maven_basedir() {
|
||||
|
||||
if [ -z "$1" ]
|
||||
then
|
||||
echo "Path not specified to find_maven_basedir"
|
||||
return 1
|
||||
fi
|
||||
|
||||
basedir="$1"
|
||||
wdir="$1"
|
||||
while [ "$wdir" != '/' ] ; do
|
||||
if [ -d "$wdir"/.mvn ] ; then
|
||||
basedir=$wdir
|
||||
break
|
||||
fi
|
||||
# workaround for JBEAP-8937 (on Solaris 10/Sparc)
|
||||
if [ -d "${wdir}" ]; then
|
||||
wdir=`cd "$wdir/.."; pwd`
|
||||
fi
|
||||
# end of workaround
|
||||
done
|
||||
echo "${basedir}"
|
||||
}
|
||||
|
||||
# concatenates all lines of a file
|
||||
concat_lines() {
|
||||
if [ -f "$1" ]; then
|
||||
echo "$(tr -s '\n' ' ' < "$1")"
|
||||
fi
|
||||
}
|
||||
|
||||
BASE_DIR=`find_maven_basedir "$(pwd)"`
|
||||
if [ -z "$BASE_DIR" ]; then
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
##########################################################################################
|
||||
# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
|
||||
# This allows using the maven wrapper in projects that prohibit checking in binary data.
|
||||
##########################################################################################
|
||||
if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo "Found .mvn/wrapper/maven-wrapper.jar"
|
||||
fi
|
||||
else
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..."
|
||||
fi
|
||||
if [ -n "$MVNW_REPOURL" ]; then
|
||||
jarUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
|
||||
else
|
||||
jarUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
|
||||
fi
|
||||
while IFS="=" read key value; do
|
||||
case "$key" in (wrapperUrl) jarUrl="$value"; break ;;
|
||||
esac
|
||||
done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties"
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo "Downloading from: $jarUrl"
|
||||
fi
|
||||
wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar"
|
||||
if $cygwin; then
|
||||
wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"`
|
||||
fi
|
||||
|
||||
if command -v wget > /dev/null; then
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo "Found wget ... using wget"
|
||||
fi
|
||||
if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
|
||||
wget "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
|
||||
else
|
||||
wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
|
||||
fi
|
||||
elif command -v curl > /dev/null; then
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo "Found curl ... using curl"
|
||||
fi
|
||||
if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
|
||||
curl -o "$wrapperJarPath" "$jarUrl" -f
|
||||
else
|
||||
curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f
|
||||
fi
|
||||
|
||||
else
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo "Falling back to using Java to download"
|
||||
fi
|
||||
javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java"
|
||||
# For Cygwin, switch paths to Windows format before running javac
|
||||
if $cygwin; then
|
||||
javaClass=`cygpath --path --windows "$javaClass"`
|
||||
fi
|
||||
if [ -e "$javaClass" ]; then
|
||||
if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo " - Compiling MavenWrapperDownloader.java ..."
|
||||
fi
|
||||
# Compiling the Java class
|
||||
("$JAVA_HOME/bin/javac" "$javaClass")
|
||||
fi
|
||||
if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
|
||||
# Running the downloader
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo " - Running MavenWrapperDownloader.java ..."
|
||||
fi
|
||||
("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR")
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
##########################################################################################
|
||||
# End of extension
|
||||
##########################################################################################
|
||||
|
||||
export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo $MAVEN_PROJECTBASEDIR
|
||||
fi
|
||||
MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
|
||||
|
||||
# For Cygwin, switch paths to Windows format before running java
|
||||
if $cygwin; then
|
||||
[ -n "$M2_HOME" ] &&
|
||||
M2_HOME=`cygpath --path --windows "$M2_HOME"`
|
||||
[ -n "$JAVA_HOME" ] &&
|
||||
JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
|
||||
[ -n "$CLASSPATH" ] &&
|
||||
CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
|
||||
[ -n "$MAVEN_PROJECTBASEDIR" ] &&
|
||||
MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"`
|
||||
fi
|
||||
|
||||
# Provide a "standardized" way to retrieve the CLI args that will
|
||||
# work with both Windows and non-Windows executions.
|
||||
MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@"
|
||||
export MAVEN_CMD_LINE_ARGS
|
||||
|
||||
WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
|
||||
|
||||
exec "$JAVACMD" \
|
||||
$MAVEN_OPTS \
|
||||
$MAVEN_DEBUG_OPTS \
|
||||
-classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
|
||||
"-Dmaven.home=${M2_HOME}" \
|
||||
"-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
|
||||
${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
|
|
@ -0,0 +1,188 @@
|
|||
@REM ----------------------------------------------------------------------------
|
||||
@REM Licensed to the Apache Software Foundation (ASF) under one
|
||||
@REM or more contributor license agreements. See the NOTICE file
|
||||
@REM distributed with this work for additional information
|
||||
@REM regarding copyright ownership. The ASF licenses this file
|
||||
@REM to you under the Apache License, Version 2.0 (the
|
||||
@REM "License"); you may not use this file except in compliance
|
||||
@REM with the License. You may obtain a copy of the License at
|
||||
@REM
|
||||
@REM https://www.apache.org/licenses/LICENSE-2.0
|
||||
@REM
|
||||
@REM Unless required by applicable law or agreed to in writing,
|
||||
@REM software distributed under the License is distributed on an
|
||||
@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
@REM KIND, either express or implied. See the License for the
|
||||
@REM specific language governing permissions and limitations
|
||||
@REM under the License.
|
||||
@REM ----------------------------------------------------------------------------
|
||||
|
||||
@REM ----------------------------------------------------------------------------
|
||||
@REM Maven Start Up Batch script
|
||||
@REM
|
||||
@REM Required ENV vars:
|
||||
@REM JAVA_HOME - location of a JDK home dir
|
||||
@REM
|
||||
@REM Optional ENV vars
|
||||
@REM M2_HOME - location of maven2's installed home dir
|
||||
@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
|
||||
@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending
|
||||
@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
|
||||
@REM e.g. to debug Maven itself, use
|
||||
@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
|
||||
@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
|
||||
@REM ----------------------------------------------------------------------------
|
||||
|
||||
@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
|
||||
@echo off
|
||||
@REM set title of command window
|
||||
title %0
|
||||
@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on'
|
||||
@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
|
||||
|
||||
@REM set %HOME% to equivalent of $HOME
|
||||
if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
|
||||
|
||||
@REM Execute a user defined script before this one
|
||||
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
|
||||
@REM check for pre script, once with legacy .bat ending and once with .cmd ending
|
||||
if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %*
|
||||
if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %*
|
||||
:skipRcPre
|
||||
|
||||
@setlocal
|
||||
|
||||
set ERROR_CODE=0
|
||||
|
||||
@REM To isolate internal variables from possible post scripts, we use another setlocal
|
||||
@setlocal
|
||||
|
||||
@REM ==== START VALIDATION ====
|
||||
if not "%JAVA_HOME%" == "" goto OkJHome
|
||||
|
||||
echo.
|
||||
echo Error: JAVA_HOME not found in your environment. >&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the >&2
|
||||
echo location of your Java installation. >&2
|
||||
echo.
|
||||
goto error
|
||||
|
||||
:OkJHome
|
||||
if exist "%JAVA_HOME%\bin\java.exe" goto init
|
||||
|
||||
echo.
|
||||
echo Error: JAVA_HOME is set to an invalid directory. >&2
|
||||
echo JAVA_HOME = "%JAVA_HOME%" >&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the >&2
|
||||
echo location of your Java installation. >&2
|
||||
echo.
|
||||
goto error
|
||||
|
||||
@REM ==== END VALIDATION ====
|
||||
|
||||
:init
|
||||
|
||||
@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
|
||||
@REM Fallback to current working directory if not found.
|
||||
|
||||
set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
|
||||
IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
|
||||
|
||||
set EXEC_DIR=%CD%
|
||||
set WDIR=%EXEC_DIR%
|
||||
:findBaseDir
|
||||
IF EXIST "%WDIR%"\.mvn goto baseDirFound
|
||||
cd ..
|
||||
IF "%WDIR%"=="%CD%" goto baseDirNotFound
|
||||
set WDIR=%CD%
|
||||
goto findBaseDir
|
||||
|
||||
:baseDirFound
|
||||
set MAVEN_PROJECTBASEDIR=%WDIR%
|
||||
cd "%EXEC_DIR%"
|
||||
goto endDetectBaseDir
|
||||
|
||||
:baseDirNotFound
|
||||
set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
|
||||
cd "%EXEC_DIR%"
|
||||
|
||||
:endDetectBaseDir
|
||||
|
||||
IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
|
||||
|
||||
@setlocal EnableExtensions EnableDelayedExpansion
|
||||
for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
|
||||
@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
|
||||
|
||||
:endReadAdditionalConfig
|
||||
|
||||
SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
|
||||
set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
|
||||
set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
|
||||
|
||||
set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
|
||||
|
||||
FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
|
||||
IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B
|
||||
)
|
||||
|
||||
@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
|
||||
@REM This allows using the maven wrapper in projects that prohibit checking in binary data.
|
||||
if exist %WRAPPER_JAR% (
|
||||
if "%MVNW_VERBOSE%" == "true" (
|
||||
echo Found %WRAPPER_JAR%
|
||||
)
|
||||
) else (
|
||||
if not "%MVNW_REPOURL%" == "" (
|
||||
SET DOWNLOAD_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
|
||||
)
|
||||
if "%MVNW_VERBOSE%" == "true" (
|
||||
echo Couldn't find %WRAPPER_JAR%, downloading it ...
|
||||
echo Downloading from: %DOWNLOAD_URL%
|
||||
)
|
||||
|
||||
powershell -Command "&{"^
|
||||
"$webclient = new-object System.Net.WebClient;"^
|
||||
"if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^
|
||||
"$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^
|
||||
"}"^
|
||||
"[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^
|
||||
"}"
|
||||
if "%MVNW_VERBOSE%" == "true" (
|
||||
echo Finished downloading %WRAPPER_JAR%
|
||||
)
|
||||
)
|
||||
@REM End of extension
|
||||
|
||||
@REM Provide a "standardized" way to retrieve the CLI args that will
|
||||
@REM work with both Windows and non-Windows executions.
|
||||
set MAVEN_CMD_LINE_ARGS=%*
|
||||
|
||||
%MAVEN_JAVA_EXE% ^
|
||||
%JVM_CONFIG_MAVEN_PROPS% ^
|
||||
%MAVEN_OPTS% ^
|
||||
%MAVEN_DEBUG_OPTS% ^
|
||||
-classpath %WRAPPER_JAR% ^
|
||||
"-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^
|
||||
%WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
|
||||
if ERRORLEVEL 1 goto error
|
||||
goto end
|
||||
|
||||
:error
|
||||
set ERROR_CODE=1
|
||||
|
||||
:end
|
||||
@endlocal & set ERROR_CODE=%ERROR_CODE%
|
||||
|
||||
if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost
|
||||
@REM check for post script, once with legacy .bat ending and once with .cmd ending
|
||||
if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat"
|
||||
if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd"
|
||||
:skipRcPost
|
||||
|
||||
@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
|
||||
if "%MAVEN_BATCH_PAUSE%"=="on" pause
|
||||
|
||||
if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE%
|
||||
|
||||
cmd /C exit /B %ERROR_CODE%
|
|
@ -0,0 +1,41 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>2.6.6</version>
|
||||
<relativePath/> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
<groupId>com.learn</groupId>
|
||||
<artifactId>learn</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<name>learn</name>
|
||||
<description>Demo project for Spring Boot</description>
|
||||
<properties>
|
||||
<java.version>1.8</java.version>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,23 @@
|
|||
package com.learn.learn;
|
||||
|
||||
public class HouseRobber1 {
|
||||
public int rob(int[] nums) {
|
||||
if (nums==null||nums.length==0){
|
||||
return 0;
|
||||
}
|
||||
// 辅助数组,用来记录中间过程
|
||||
int[] sum = new int[nums.length];
|
||||
sum[0]=nums[0];
|
||||
if (nums.length==1){
|
||||
return nums[0];
|
||||
}
|
||||
sum[1] = Math.max(nums[0],nums[1]);
|
||||
if (nums.length==2){
|
||||
return sum[1];
|
||||
}
|
||||
for (int i=2;i<nums.length;i++){
|
||||
sum[i]=Math.max(nums[i]+sum[i-2],sum[i-1]);
|
||||
}
|
||||
return sum[nums.length-1];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
package com.learn.learn;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public class HouseRobber2 {
|
||||
public static void main(String[] args) {
|
||||
int[] nums = new int[]{7,6,10,8,9,11};
|
||||
System.out.println(rob(nums));
|
||||
}
|
||||
public static int rob(int[] nums) {
|
||||
if (nums==null||nums.length==0){
|
||||
return 0;
|
||||
}
|
||||
if (nums.length==1){
|
||||
return nums[0];
|
||||
}
|
||||
if (nums.length==2){
|
||||
return Math.max(nums[0],nums[1]);
|
||||
}
|
||||
int[] memo=new int[nums.length];
|
||||
Arrays.fill(memo, -1);
|
||||
int result = tryRob(nums,0,memo);
|
||||
// Arrays.stream(Arrays.stream(memo).toArray()).forEach(System.out::println);
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
从当前值开始,往后累加和,数值不连续。
|
||||
*/
|
||||
private static int tryRob(int[] nums, int index,int[] memo) {
|
||||
if (index >= nums.length) {
|
||||
return 0;
|
||||
}
|
||||
// 记忆化搜索可以避免重叠子问题的重复运算
|
||||
if (memo[index] != -1) {
|
||||
return memo[index];
|
||||
}
|
||||
// 当前值和当前值后两项值中比较大的值。
|
||||
int res = 0;
|
||||
for (int i = index; i < nums.length; i++) {
|
||||
// 使用当前值
|
||||
int indexValue = nums[i] + tryRob(nums, i + 2,memo);
|
||||
res = Math.max(res, indexValue);
|
||||
}
|
||||
memo[index] = res;
|
||||
return res;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package com.learn.learn;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class LearnApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(LearnApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,114 @@
|
|||
package com.learn.learn;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/*
|
||||
给定一个已排序的正整数数组 nums ,和一个正整数 n 。从 [1, n] 区间内选取任意个数字补充到 nums 中,使得 [1, n] 区间内的任何数字都可以用 nums 中某几个数字的和来表示。
|
||||
|
||||
请返回 满足上述要求的最少需要补充的数字个数 。
|
||||
|
||||
来源:力扣(LeetCode)
|
||||
链接:https://leetcode-cn.com/problems/patching-array
|
||||
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
|
||||
*/
|
||||
public class PatchingArray {
|
||||
|
||||
public static void main(String[] args) {
|
||||
int [] arr = {1,3};
|
||||
System.out.println(minPatches(arr,6));
|
||||
}
|
||||
|
||||
public static int minPatches(int[] nums, int n) {
|
||||
int result =0;
|
||||
// 边界
|
||||
if (n==0){
|
||||
return 0;
|
||||
}
|
||||
// nums为空或者长度为0则需要补充数据
|
||||
// 从0-n,判断哪些数据没有满足
|
||||
boolean dp[]=new boolean[n+1];
|
||||
// 原始数据
|
||||
for (int num : nums) {
|
||||
dp[num] = true;
|
||||
}
|
||||
List<Integer> different = judeIsSame(dp);
|
||||
// 判断是否相同
|
||||
if (different.size()==0){
|
||||
return result;
|
||||
}
|
||||
// 添加所有累加结果,每个值要与不要。
|
||||
addSum(dp,nums,0,0);
|
||||
different = judeIsSame(dp);
|
||||
if (different.size()==0){
|
||||
return result;
|
||||
}
|
||||
// 补充参数,不同参数相差为几则需要几个。
|
||||
// 相差数相同则为一个
|
||||
Set<Integer> setSumDifferent = new HashSet<>();
|
||||
for (int i = 1; i < different.size(); i++) {
|
||||
setSumDifferent.add(different.get(i)-different.get(i-1));
|
||||
}
|
||||
// 几个数的和可以的出第三者则删除第三者。
|
||||
List<Integer> objects = new ArrayList<>(setSumDifferent);
|
||||
List<Integer> need = new ArrayList<>();
|
||||
getSumDifferent(objects,need,0,1,2);
|
||||
return new HashSet<>(need).size();
|
||||
}
|
||||
|
||||
public static void getSumDifferent(List<Integer> objects,List<Integer> need,int fist,int next,int current){
|
||||
if (objects.size()==1){
|
||||
need.add(objects.get(0));
|
||||
return;
|
||||
}
|
||||
if (objects.size()==2){
|
||||
need.add(objects.get(0));
|
||||
need.add(objects.get(1));
|
||||
return;
|
||||
}
|
||||
if (current==objects.size()){
|
||||
return;
|
||||
}
|
||||
// 不用object2
|
||||
need.add(objects.get(fist));
|
||||
need.add(objects.get(next));
|
||||
if (objects.get(fist)+objects.get(next)==objects.get(current)){
|
||||
objects.remove(current);
|
||||
getSumDifferent(objects,need,++fist,++next,++current);
|
||||
}
|
||||
if (objects.get(fist)+objects.get(next)>objects.get(current)){
|
||||
need.add(objects.get(current));
|
||||
getSumDifferent(objects,need,fist,next,++current);
|
||||
}
|
||||
if (objects.get(fist)+objects.get(next)<objects.get(current)){
|
||||
need.add(objects.get(current));
|
||||
getSumDifferent(objects,need,++fist,++next,current);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public static void addSum(boolean dp[],int[] arr,int sum,int index){
|
||||
if (index==arr.length){
|
||||
dp[sum]=true;
|
||||
return;
|
||||
};
|
||||
int next = index+1;
|
||||
addSum(dp,arr,sum,next);
|
||||
addSum(dp,arr,sum+arr[index],next);
|
||||
}
|
||||
|
||||
/*
|
||||
除了第0位之外是否全部为ture,返回不为true的位置
|
||||
*/
|
||||
public static List<Integer> judeIsSame(boolean dp[]){
|
||||
List<Integer> falseList = new ArrayList<>();
|
||||
for (int i = 1; i < dp.length; i++) {
|
||||
if (!dp[i]){
|
||||
falseList.add(i);
|
||||
}
|
||||
}
|
||||
return falseList;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
package com.learn.learn.dachang.eleven;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class PalindromePartitioningll {
|
||||
|
||||
public static int minCut(String s){
|
||||
if (s==null||s.length()==0){
|
||||
return 0;
|
||||
}
|
||||
char[] str = s.toCharArray();
|
||||
int n=str.length;
|
||||
boolean[][] checkMap = createCheckMap(str,n);
|
||||
int[] dp = new int [n+1];
|
||||
dp[n]=0;
|
||||
for (int i=n-1;i>=0;i--){
|
||||
if (checkMap[i][n-1]){
|
||||
dp[i]=1;
|
||||
}else {
|
||||
int next = Integer.MAX_VALUE;
|
||||
for (int j=i;j<n;j++){
|
||||
if (checkMap[i][j]){
|
||||
next = Math.min(next,dp[j+1]);
|
||||
}
|
||||
}
|
||||
dp[i]=1+next;
|
||||
}
|
||||
}
|
||||
return dp[0]-1;
|
||||
}
|
||||
|
||||
public static boolean[][]createCheckMap(char[] str,int n){
|
||||
boolean[][] ans = new boolean[n][n];
|
||||
for (int i=0;i<n;i++){
|
||||
ans[i][i]=true;
|
||||
ans[i][i+1]=str[i]==str[i+1];
|
||||
}
|
||||
ans[n-1][n-1]=true;
|
||||
for (int i=n-3;i>=0;i--){
|
||||
for (int j=i+2;j<n;j++){
|
||||
ans[i][j]=str[i]==str[j]&&ans[i+1][j-1];
|
||||
}
|
||||
}
|
||||
return ans;
|
||||
}
|
||||
|
||||
public static List<String> minCutOneWay(String s){
|
||||
List<String> ans = new ArrayList<>();
|
||||
if (s==null||s.length()<2){
|
||||
ans.add(s);
|
||||
}else {
|
||||
char[] str = s.toCharArray();
|
||||
int n = str.length;
|
||||
boolean[][] checkMap = createCheckMap(str,n);
|
||||
int[] dp = new int [n+1];
|
||||
dp[n]=0;
|
||||
for (int i = n-1;i>=0;i--){
|
||||
if (checkMap[i][n-1]){
|
||||
dp[i]=1;
|
||||
}else {
|
||||
int next = Integer.MAX_VALUE;
|
||||
for (int j=i;j<n;j++){
|
||||
if (checkMap[i][j]){
|
||||
next = Math.min(next,dp[j+1]);
|
||||
}
|
||||
}
|
||||
dp[i]=1+next;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ans;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package com.learn.learn.dachang.four;
|
||||
|
||||
public class MaxSubArr {
|
||||
public int maxSubArray(int[] nums) {
|
||||
if (nums==null||nums.length==0){
|
||||
return 0;
|
||||
}
|
||||
int pre = nums[0];
|
||||
// 记录最大值,中间有些可能会忽略10,-10,5
|
||||
int max = nums[0];
|
||||
for (int i=1;i<nums.length;i++){
|
||||
pre = Math.max(pre + nums[i], nums[i]);
|
||||
max=Math.max(pre,max);
|
||||
}
|
||||
return max;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
package com.learn.learn.dachang.one;
|
||||
|
||||
public class Five {
|
||||
public int longestIncreasingPath(int [][] matrix){
|
||||
int ans = 0;
|
||||
int n= matrix.length;
|
||||
int m = matrix[0].length;
|
||||
for (int i=0;i<n;i++){
|
||||
for (int j=0;j<m;j++){
|
||||
ans=Math.max(ans,process(matrix,i,j));
|
||||
}
|
||||
}
|
||||
return ans;
|
||||
}
|
||||
public int process(int [][]m,int i,int j){
|
||||
int up = i>0&&m[i][j]<m[i-1][j]?process(m,i-1,j):0;
|
||||
int down = i<(m.length-1)&&m[i][j]<m[i+1][j]?process(m,i+1,j):0;
|
||||
int left = j>0&&m[i][j]<m[i][j-1]?process(m,i,j-1):0;
|
||||
int right=j<(m[0].length-1)&&m[i][j]<m[i][j+1]?process(m,i,j+1):0;
|
||||
return Math.max(Math.max(up,down),Math.max(left,right))+1;
|
||||
}
|
||||
// 动态规划,记忆化搜索
|
||||
public int longestIncreasingPath2(int [][] matrix){
|
||||
int ans = 0;
|
||||
int n= matrix.length;
|
||||
int m = matrix[0].length;
|
||||
int [][] dp = new int[n][m];
|
||||
for (int i=0;i<n;i++){
|
||||
for (int j=0;j<m;j++){
|
||||
ans=Math.max(ans,process2(matrix,i,j,dp));
|
||||
}
|
||||
}
|
||||
return ans;
|
||||
}
|
||||
public int process2(int [][]m,int i,int j,int [][] dp){
|
||||
if (dp[i][j]!=0){
|
||||
return dp[i][j];
|
||||
}
|
||||
int up = i>0&&m[i][j]<m[i-1][j]?process(m,i-1,j):0;
|
||||
int down = i<(m.length-1)&&m[i][j]<m[i+1][j]?process(m,i+1,j):0;
|
||||
int left = j>0&&m[i][j]<m[i][j-1]?process(m,i,j-1):0;
|
||||
int right=j<(m[0].length-1)&&m[i][j]<m[i][j+1]?process(m,i,j+1):0;
|
||||
int result = Math.max(Math.max(up,down),Math.max(left,right))+1;
|
||||
dp[i][j]= result;
|
||||
return result;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package com.learn.learn.dachang.one;
|
||||
|
||||
public class Fourth {
|
||||
public int minTime(String abc){
|
||||
char[] chars = abc.toCharArray();
|
||||
int gIndex=0;
|
||||
int gTimes=0;
|
||||
int bIndex=0;
|
||||
int bTimes=0;
|
||||
for (int i=0;i<chars.length;i++){
|
||||
if (chars[i]=='G'){
|
||||
// 让G在左边
|
||||
gTimes+=(i-gIndex);
|
||||
gIndex++;
|
||||
//gTimes+=i-(gIndex++);
|
||||
}else {
|
||||
// 让B在左边
|
||||
bTimes+=(i-bIndex);
|
||||
bIndex++;
|
||||
//bTimes+=i-(bIndex++);
|
||||
}
|
||||
}
|
||||
return Math.min(gTimes,bTimes);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
package com.learn.learn.dachang.one;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
//494
|
||||
public class Seven {
|
||||
|
||||
/*
|
||||
暴力递归
|
||||
*/
|
||||
public int process1(int [] arr,int index,int rest){
|
||||
if (index==arr.length){
|
||||
return rest==0?1:0;
|
||||
}
|
||||
// 加和减的次数总和
|
||||
return process1(arr,index+1,rest-arr[index])+process1(arr,index+1,rest+arr[index]);
|
||||
}
|
||||
/*
|
||||
记忆化搜索(使用缓存),index和rest
|
||||
|
||||
优化点
|
||||
1.所有的数取绝对值,不影响结果
|
||||
2.所有数累加和小于目标值,则不存在结果
|
||||
3.所有数的加减结果奇偶性不变
|
||||
4.2p=t+p+n-----------------p-n=t 背包问题
|
||||
5.二维动态规划的孔家压缩技巧
|
||||
动态规划
|
||||
*/
|
||||
public int proces2(int [] arr, int index, int rest, HashMap<Integer,HashMap<Integer,Integer>> dp){
|
||||
// 用缓存
|
||||
if (dp.containsKey(index)&&dp.get(index).containsKey(rest)){
|
||||
return dp.get(index).get(rest);
|
||||
}
|
||||
int result=0;
|
||||
if (index==arr.length){
|
||||
result= (rest==0?1:0);
|
||||
}else {
|
||||
result = process1(arr,index+1,rest-arr[index])+process1(arr,index+1,rest+arr[index]);
|
||||
}
|
||||
// 建立缓存
|
||||
if (!dp.containsKey(index)){
|
||||
dp.putAll(new HashMap<>());
|
||||
}
|
||||
dp.get(index).put(rest,result);
|
||||
return result;
|
||||
}
|
||||
|
||||
public int process3(int [] arr,int target){
|
||||
int sum = 0;
|
||||
for (int n:arr){
|
||||
sum+=n;
|
||||
}
|
||||
return sum<target||((target&1)^(sum&1))!=0?0:subSet(arr,(target+sum)>>1);
|
||||
}
|
||||
public int subSet(int[] nums,int s){
|
||||
int[]dp = new int[s+1];
|
||||
dp[0]=1;
|
||||
for (int n:nums){
|
||||
for (int i = s;i>=n;i--){
|
||||
dp[i]+=dp[i-n];
|
||||
}
|
||||
}
|
||||
return dp[s];
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package com.learn.learn.dachang.one;
|
||||
|
||||
public class Third {
|
||||
public int getTwo(int start){
|
||||
start--;
|
||||
start|=(start>>>1);
|
||||
start|=start|(start>>>2);
|
||||
start|=start|(start>>>4);
|
||||
start|=start|(start>>>8);
|
||||
start|=start|(start>>>16);
|
||||
return start<0?1:start+1;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package com.learn.learn.dachang.second;
|
||||
|
||||
public class Fourth {
|
||||
public static int maxMoney(int[][] income){
|
||||
if (income==null||income.length<2||(income.length&1)!=0){
|
||||
return 0;
|
||||
}
|
||||
int n=income.length;
|
||||
int m=n>>1;
|
||||
return process(income,0,m);
|
||||
}
|
||||
// index .....所有司机,往A和B区域分配
|
||||
// A区域还有rest个名额
|
||||
// 返回把index司机分配完,最终A和B区域相同,
|
||||
public static int process(int[][] income,int index,int rest){
|
||||
if(index==income.length){
|
||||
return 0;
|
||||
}
|
||||
if (income.length-index ==rest){
|
||||
return income[index][0]+process(income,index+1,rest-1);
|
||||
}
|
||||
if (rest==0){
|
||||
return income[index][1]+process(income,index+1,rest);
|
||||
}
|
||||
int p1 = income[index][0]+process(income,index+1,rest-1);
|
||||
int p2 = income[index][1]+process(income,index+1,rest);
|
||||
return Math.max(p1,p2);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
package com.learn.learn.dachang.seventeen;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
public class DistinctSubsequencesIi {
|
||||
public static int process(String s){
|
||||
if (s==null||s.length()==0){
|
||||
return 0;
|
||||
}
|
||||
char[] str = s.toCharArray();
|
||||
HashMap<Character,Integer> map = new HashMap<>();
|
||||
int all = 1;
|
||||
for (char x:str){
|
||||
int newAdd = all;
|
||||
int curAll = all+newAdd-(map.containsKey(x)?map.get(x)-1:0);
|
||||
all = curAll;
|
||||
map.put(x,newAdd);
|
||||
}
|
||||
return all;
|
||||
}
|
||||
|
||||
public int distinctSubseqII(String s) {
|
||||
if (s==null||s.length()==0){
|
||||
return 0;
|
||||
}
|
||||
char[] str = s.toCharArray();
|
||||
int i = 1000000007;
|
||||
HashMap<Character,Integer> map = new HashMap<>();
|
||||
int all = 1;
|
||||
for (char x:str){
|
||||
int newAdd = all;
|
||||
int curAll = all;
|
||||
curAll = (curAll+newAdd)%i;
|
||||
curAll=(curAll-(map.containsKey(x)?map.get(x):0)+i)%i;
|
||||
all = curAll;
|
||||
map.put(x,newAdd);
|
||||
}
|
||||
return all-1;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
package com.learn.learn.dachang.seventeen;
|
||||
|
||||
public class StringST {
|
||||
public static int dp(String s1,String t1){
|
||||
char[] s = s1.toCharArray();
|
||||
char[] t = t1.toCharArray();
|
||||
int n=s.length;
|
||||
int m=t.length;
|
||||
int[][] dp = new int[n][m];
|
||||
dp[0][0] = s[0]==t[0]?1:0;
|
||||
for (int i = 1;i<n;i++){
|
||||
dp[i][0]=s[i]==t[0]?(dp[i-1][0]+1):dp[i-1][0];
|
||||
}
|
||||
for (int i = 1;i<n;i++){
|
||||
for (int j=1;j<=Math.min(i,m-1);j++){
|
||||
dp[i][j]=dp[i-1][j];
|
||||
if (s[i]==t[i]){
|
||||
dp[i][j]+=dp[i-1][j-1];
|
||||
}
|
||||
}
|
||||
}
|
||||
return dp[n-1][m-1];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,80 @@
|
|||
package com.learn.learn.dachang.sixteen;
|
||||
|
||||
public class First {
|
||||
|
||||
public static void main(String[] args) {
|
||||
int[] arr = {1,2,3,4,5,6};
|
||||
System.out.println(checkSuccess(arr,100));
|
||||
System.out.println(checkSuccess(arr,-1));
|
||||
System.out.println(checkSuccess(arr,5));
|
||||
System.out.println(checkSuccess(arr,9));
|
||||
|
||||
//
|
||||
}
|
||||
|
||||
public static boolean checkSuccess1(int [] arr,int k){
|
||||
if (k == 0){
|
||||
return true;
|
||||
}
|
||||
if (arr == null || arr.length ==0){
|
||||
return false;
|
||||
}
|
||||
int max = 0;
|
||||
int min = 0;
|
||||
for (int i:arr){
|
||||
if (i>0){
|
||||
max +=i;
|
||||
}else {
|
||||
min+=i;
|
||||
}
|
||||
}
|
||||
if (k>max||k<min){
|
||||
return false;
|
||||
}
|
||||
return process1(arr,0,k);
|
||||
}
|
||||
public static boolean process1(int[] arr,int index,int sum){
|
||||
if (index ==-1){
|
||||
return false;
|
||||
}
|
||||
if (sum==0){
|
||||
return true;
|
||||
}
|
||||
int next = index++;
|
||||
return process1(arr,next,sum-arr[index])||process1(arr,next,sum);
|
||||
}
|
||||
public static boolean checkSuccess(int [] arr,int k){
|
||||
// 边界及验证数据有效性
|
||||
if (k == 0){
|
||||
return true;
|
||||
}
|
||||
if (arr == null || arr.length ==0){
|
||||
return false;
|
||||
}
|
||||
int max = 0;
|
||||
int min = 0;
|
||||
for (int i:arr){
|
||||
if (i>0){
|
||||
max +=i;
|
||||
}else {
|
||||
min+=i;
|
||||
}
|
||||
}
|
||||
if (k>max||k<min){
|
||||
return false;
|
||||
}
|
||||
return add(0,arr,k,0);
|
||||
|
||||
}
|
||||
public static boolean add(int index,int [] arr,int k,int sum){
|
||||
if (sum ==k){
|
||||
return true;
|
||||
}
|
||||
if (index == arr.length){
|
||||
return false;
|
||||
}
|
||||
int next = index+1;
|
||||
// 当前值要和不要两种情况
|
||||
return add(next,arr,k,sum)||add(next,arr,k,sum+arr[index]);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
package com.learn.learn.dachang.thirteen;
|
||||
|
||||
/**
|
||||
* ## 题目一
|
||||
* 面值为1-N的牌组成一组
|
||||
* 每次你从组里等概率的抽出1-n中的一张
|
||||
* 下次抽会换一组新的,有无限组
|
||||
* 当累加和<a时,你将一直抽牌
|
||||
* 当累加和>=a且<b时,你将获胜
|
||||
* 当累加和>=b时,你将失败
|
||||
* 返回获胜的概率,给定的参数为N,a,b
|
||||
*/
|
||||
public class Code1NCardsABWin {
|
||||
|
||||
|
||||
|
||||
|
||||
public static double f2(int n,int a,int b){
|
||||
if (n<1||a>=b||a<0||b<0){
|
||||
return 0;
|
||||
}
|
||||
// 拿牌最终结果必定在a-b中间
|
||||
if (b-a>=n){
|
||||
return 1.0;
|
||||
}
|
||||
// 所有参数都合法,并且可能出现失败
|
||||
return p2(0,n,a,b);
|
||||
}
|
||||
|
||||
public static double p2(int cur,int n,int a,int b){
|
||||
if (cur>a&&cur<b){
|
||||
return 1;
|
||||
}
|
||||
if (cur>b){
|
||||
return 0;
|
||||
}
|
||||
double w = 0.0;
|
||||
for (int i=1;i<n;i++){
|
||||
w+=p2(cur+1,n,a,b);
|
||||
}
|
||||
return w/n;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public static double f1(){
|
||||
return p1(0);
|
||||
}
|
||||
public static double p1(int cur){
|
||||
if (cur>=17&&cur<=21){
|
||||
return 1;
|
||||
}
|
||||
if (cur>=21){
|
||||
return 0.0;
|
||||
}
|
||||
double w = 0.0;
|
||||
for (int i = 1;i<10;i++){
|
||||
// 加每张牌获胜的概率
|
||||
w+=p1(cur+i);
|
||||
}
|
||||
// 求平均
|
||||
return w/10;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
package com.learn.learn.dachang.twentyfour;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class Code04_Painting {
|
||||
public static int minColors(int N, int M) {
|
||||
// 颜色数量是i
|
||||
for (int i = 2; i < N * M; i++) {
|
||||
int[][] matrix = new int[N][M];
|
||||
// 下面这一句可知,需要的最少颜色数i,一定是N*M的某个因子
|
||||
if ((N * M) % i == 0 && can(matrix, N, M, i)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return N * M;
|
||||
}
|
||||
|
||||
// 在matrix上染色,返回只用pNum种颜色是否可以做到要求
|
||||
public static boolean can(int[][] matrix, int N, int M, int pNum) {
|
||||
int all = N * M;
|
||||
int every = all / pNum;
|
||||
// 使用颜料总数
|
||||
ArrayList<Integer> rest = new ArrayList<>();
|
||||
rest.add(0);
|
||||
for (int i = 1; i <= pNum; i++) {
|
||||
rest.add(every);
|
||||
}
|
||||
return process(matrix, N, M, pNum, 0, 0, rest);
|
||||
}
|
||||
|
||||
public static boolean process(int[][] matrix, int N, int M, int pNum, int row, int col, List<Integer> rest) {
|
||||
// 从第0行第0列开始,到N时结束,到M时进行下一行.
|
||||
if (row == N) {
|
||||
return true;
|
||||
}
|
||||
if (col == M) {
|
||||
return process(matrix, N, M, pNum, row + 1, 0, rest);
|
||||
}
|
||||
// 为0表示没有颜色,第0列左边没有颜色,第0行上一行没有颜色
|
||||
int left = col == 0 ? 0 : matrix[row][col - 1];
|
||||
int up = row == 0 ? 0 : matrix[row - 1][col];
|
||||
for (int color = 1; color <= pNum; color++) {
|
||||
if (color != left && color != up && rest.get(color) > 0) {
|
||||
int count = rest.get(color);
|
||||
rest.set(color, count - 1);
|
||||
matrix[row][col] = color;
|
||||
if (process(matrix, N, M, pNum, row, col + 1, rest)) {
|
||||
return true;
|
||||
}
|
||||
// 不成功恢复现场.
|
||||
rest.set(color, count);
|
||||
matrix[row][col] = 0;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
// 根据代码16行的提示,打印出答案,看看是答案是哪个因子
|
||||
for (int N = 2; N < 10; N++) {
|
||||
for (int M = 2; M < 10; M++) {
|
||||
System.out.println("N = " + N);
|
||||
System.out.println("M = " + M);
|
||||
System.out.println("ans = " + minColors(N, M));
|
||||
System.out.println("===========");
|
||||
}
|
||||
}
|
||||
// 打印答案,分析可知,是N*M最小的质数因子,原因不明,也不重要
|
||||
// 反正打表法猜出来了
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
package com.learn.learn.tixi.fourty.fourth;
|
||||
// https://leetcode.com/problems/can-i-win/submissions/
|
||||
public class CanIWinFirst {
|
||||
// 对方先面对小于等于0的数字则自己赢.
|
||||
public boolean canIWin(int chose,int total){
|
||||
// 题目要求上来就是0,则先手赢
|
||||
if(total<=0){
|
||||
return true;
|
||||
}
|
||||
// 所有数字和小于提供
|
||||
if ((chose*(chose+1)>>1)<total){
|
||||
return false;
|
||||
}
|
||||
// 初始化数组
|
||||
int[]arr = new int[chose];
|
||||
for (int i=0;i<chose;i++){
|
||||
arr[i]=i+1;
|
||||
}
|
||||
return process(arr,total);
|
||||
}
|
||||
|
||||
private boolean process(int[] arr, int total) {
|
||||
if (total<=0){
|
||||
return false;
|
||||
}
|
||||
for (int i = 0;i<arr.length;i++){
|
||||
//可以拿
|
||||
int get = arr[i];
|
||||
if (get!=-1){
|
||||
|
||||
// 清理现场 开始
|
||||
arr[i]=-1;
|
||||
// 后手拿
|
||||
boolean next = process(arr, total - get);
|
||||
arr[i]=get;
|
||||
// 清理现场 结束
|
||||
|
||||
// 后手输了表示先手赢
|
||||
if (!next){
|
||||
return true;
|
||||
}
|
||||
// 后手赢了,测试下轮,从第二个开始拿,第一个自己没有拿,清理现场
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
package com.learn.learn.tixi.fourty.fourth;
|
||||
// https://leetcode.com/problems/can-i-win/submissions/
|
||||
public class CanIWinSecond {
|
||||
// 对方先面对小于等于0的数字则自己赢.
|
||||
public boolean canIWin(int maxChoosableInteger, int desiredTotal) {
|
||||
// 题目要求上来就是0,则先手赢
|
||||
if(desiredTotal<=0){
|
||||
return true;
|
||||
}
|
||||
// 所有数字和小于提供
|
||||
if ((maxChoosableInteger*(maxChoosableInteger+1)>>1)<desiredTotal){
|
||||
return false;
|
||||
}
|
||||
int[]dp = new int[1<<(maxChoosableInteger+1)];
|
||||
return process(maxChoosableInteger,0,desiredTotal,dp);
|
||||
}
|
||||
|
||||
private boolean process(int chose,int state, int total,int[] dp) {
|
||||
if (dp[state]!=0){
|
||||
return dp[state]==1?true:false;
|
||||
}
|
||||
boolean result = false;
|
||||
if(total>0){
|
||||
for (int i = 1;i<=chose;i++){
|
||||
if (((1<<i) & state)==0){
|
||||
if (!process(chose,(state|(1<<i)),total-i,dp)){
|
||||
result = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
dp[state]=result?1:-1;
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package com.learn.learn.tixi.fourty.fourth;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class TSPFirst {
|
||||
public static int fun(int[][] matrix, List<Integer> set, int start){
|
||||
int cityNum = 1;
|
||||
for (int i=0;i<set.size();i++){
|
||||
if (set.get(i)!=null){
|
||||
cityNum++;
|
||||
}
|
||||
}
|
||||
if (cityNum==1){
|
||||
return matrix[start][0];
|
||||
}
|
||||
set.set(start,null);
|
||||
int min = Integer.MAX_VALUE;
|
||||
for (int i=0;i<set.size();i++){
|
||||
if (set.get(i)!=null){
|
||||
int cur = matrix[start][i]+fun(matrix,set,i);
|
||||
min=Math.min(min,cur);
|
||||
}
|
||||
}
|
||||
set.set(start,1);
|
||||
return min;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,115 @@
|
|||
package com.learn.learn.tixi.nineteenth;
|
||||
|
||||
/*
|
||||
给定一个整型数组arr,代表数值不同的纸牌排成一条线,玩家A和玩家B依次拿走每张纸牌,
|
||||
规定玩家A先拿,玩家B后拿,但是每个玩家每次只能拿走最左边或者最右边的纸牌,玩家A和玩家B都绝顶聪明,
|
||||
请返回最后获胜者的分数。[50,100,20,10]
|
||||
*/
|
||||
public class Code03 {
|
||||
public static void main(String[] args) {
|
||||
int [] arra = {5,7,4,5,8,1,6,0,3,4,6,1,7};
|
||||
System.out.println(win1(arra));
|
||||
System.out.println(win2(arra));
|
||||
System.out.println(win3(arra));
|
||||
}
|
||||
|
||||
// ====================================================暴力递归======================================================
|
||||
public static int win1(int[] arr){
|
||||
if (arr==null||arr.length==0){
|
||||
return 0;
|
||||
}
|
||||
int first = f(arr,0,arr.length-1);
|
||||
int second = g(arr,0,arr.length-1);
|
||||
return Math.max(first,second);
|
||||
|
||||
}
|
||||
public static int f(int[] arr,int l,int r){
|
||||
if (l==r){
|
||||
return arr[l];
|
||||
}
|
||||
int p1 = arr[l]+g(arr,l+1,r);
|
||||
int p2 = arr[r]+g(arr,l,r-1);
|
||||
return Math.max(p1,p2);
|
||||
}
|
||||
public static int g(int[] arr ,int l,int r){
|
||||
if (l==r){
|
||||
return 0;
|
||||
}
|
||||
int p1= f(arr,l+1,r);// 对手拿走了L位置的数
|
||||
int p2= f(arr,l,r-1);// 对手拿走了R位置的数
|
||||
return Math.min(p1,p2);
|
||||
}
|
||||
|
||||
// ====================================================添加缓存======================================================
|
||||
|
||||
public static int win2(int[] arr){
|
||||
if (arr==null||arr.length==0){
|
||||
return 0;
|
||||
}
|
||||
int size = arr.length;
|
||||
int[][] fmap = new int[size][size];
|
||||
int[][] gmap = new int[size][size];
|
||||
for (int i = 0;i<size;i++){
|
||||
for (int j = 0;j<size;j++){
|
||||
fmap[i][j]=-1;
|
||||
gmap[i][j]=-1;
|
||||
}
|
||||
}
|
||||
|
||||
int first = f2(arr,0,arr.length-1,fmap,gmap);
|
||||
int second = g2(arr,0,arr.length-1,fmap,gmap);
|
||||
return Math.max(first,second);
|
||||
|
||||
}
|
||||
public static int f2(int[] arr,int l,int r,int[][] fmap,int[][] gmap){
|
||||
if (fmap[l][r]!=-1){
|
||||
return fmap[l][r];
|
||||
}
|
||||
int result = 0;
|
||||
if (l==r){
|
||||
result= arr[l];
|
||||
}else {
|
||||
int p1 = arr[l]+g2(arr,l+1,r,fmap,gmap);
|
||||
int p2 = arr[r]+g2(arr,l,r-1,fmap,gmap);
|
||||
result= Math.max(p1,p2);
|
||||
}
|
||||
fmap[l][r]=result;
|
||||
return result;
|
||||
}
|
||||
public static int g2(int[] arr ,int l,int r,int[][] fmap,int[][] gmap){
|
||||
if (gmap[l][r]!=-1){
|
||||
return gmap[l][r];
|
||||
}
|
||||
int result = 0;
|
||||
if (l!=r){
|
||||
int p1= f2(arr,l+1,r,fmap,gmap);
|
||||
int p2= f2(arr,l,r-1,fmap,gmap);
|
||||
result = Math.min(p1,p2);
|
||||
}
|
||||
gmap[l][r]=result;
|
||||
return result;
|
||||
}
|
||||
// ====================================================动态规划,严格表依赖======================================================
|
||||
public static int win3(int[] arr){
|
||||
if (arr==null||arr.length==0){
|
||||
return 0;
|
||||
}
|
||||
int size = arr.length;
|
||||
int[][] fmap = new int[size][size];
|
||||
int[][] gmap = new int[size][size];
|
||||
for (int i = 0;i<size;i++){
|
||||
fmap[i][i]=arr[i];
|
||||
}
|
||||
for (int startCol = 1;startCol<size;startCol++){
|
||||
int l = 0;
|
||||
int r = startCol;
|
||||
while (r<size){
|
||||
fmap[l][r] = Math.max(arr[l]+gmap[l+1][r],arr[r]+gmap[l][r-1]);
|
||||
gmap[l][r] = Math.min(fmap[l+1][r],fmap[l][r-1]);
|
||||
l++;
|
||||
r++;
|
||||
}
|
||||
}
|
||||
return Math.max(fmap[0][size-1],gmap[0][size-1]);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
package com.learn.learn.tixi.thirty.first;
|
||||
|
||||
public class MorrisTraversal {
|
||||
class Node{
|
||||
public Node left;
|
||||
public Node right;
|
||||
public int value;
|
||||
}
|
||||
public static void morris(Node head){
|
||||
if (head==null){
|
||||
return;
|
||||
}
|
||||
Node cur = head;
|
||||
Node mostRight = null;
|
||||
while(cur!=null){
|
||||
mostRight = cur.left;
|
||||
if (mostRight!=null){
|
||||
while (mostRight.right!=null&&mostRight.right!=cur){
|
||||
mostRight= mostRight.right;
|
||||
}
|
||||
// mostRight cur左树上最右节点
|
||||
if (mostRight.right==null){
|
||||
mostRight.right=cur;
|
||||
cur=cur.left;
|
||||
continue;
|
||||
}else { // mostRight.right==cur
|
||||
mostRight.right=null;
|
||||
}
|
||||
}
|
||||
cur=cur.right;
|
||||
}
|
||||
}
|
||||
|
||||
// 返回x为头的数,最小深度是多少
|
||||
public static int p(Node x){
|
||||
if (x.left==null&&x.right==null){
|
||||
return 1;
|
||||
}
|
||||
// 左右子树起码一个为不空
|
||||
int left = Integer.MAX_VALUE;
|
||||
if (x.left!=null){
|
||||
left=p(x.left);
|
||||
}
|
||||
int right = Integer.MAX_VALUE;
|
||||
if (x.right!=null){
|
||||
right = p(x.right);
|
||||
}
|
||||
return 1+Math.max(left,right);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
package com.learn.learn.tixi.thirty.zero;
|
||||
|
||||
public class FindMinKth {
|
||||
|
||||
// 改写快排,时间复杂度O(N)
|
||||
public static int minKth2(int[] arry,int k){
|
||||
int [] arr = copyArray(arry);
|
||||
return process2(arr,0,arr.length-1,k-1);
|
||||
}
|
||||
|
||||
public static int [] copyArray(int[] arr){
|
||||
int[] ans = new int[arr.length];
|
||||
for (int i=0;i!=ans.length;i++){
|
||||
ans[i]=arr[i];
|
||||
}
|
||||
return ans;
|
||||
}
|
||||
|
||||
// arr 第k小的数
|
||||
// process2(arr,0,n-1,k-1)
|
||||
// arr[L...R] 范围上,如果排序的话(不是真的去排序),找位于index的数
|
||||
// index 在[L..R]范围
|
||||
public static int process2(int[] arr,int l,int r,int index){
|
||||
if (l==r){
|
||||
return arr[l];
|
||||
}
|
||||
// 不止一个数 l+[0,r-l]
|
||||
int pivot = arr[l+(int) (Math.random()*(r-l+1))];
|
||||
// range[0] range[1]
|
||||
// l .....r pivot
|
||||
// 0 .....1000 70....800
|
||||
int [] range = partition(arr,l,r,pivot);
|
||||
if (index>=range[0]&&index<=range[1]){
|
||||
return arr[index];
|
||||
}else if (index<range[0]){
|
||||
return process2(arr,l,range[0]-1,index);
|
||||
}else {
|
||||
return process2(arr,range[1]+1,r,index);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static int minKth(int[] arr,int index){
|
||||
int l = 0;
|
||||
int r=arr.length-1;
|
||||
int pivot =0;
|
||||
int [] range =null;
|
||||
while (l<r){
|
||||
pivot = arr[l+(int) (Math.random()*(r-l+1))];
|
||||
range = partition(arr,l,r,pivot);
|
||||
if (index<range[0]){
|
||||
r=range[0]-1;
|
||||
}else if (index>range[1]){
|
||||
l=range[1]+1;
|
||||
}else {
|
||||
return pivot;
|
||||
}
|
||||
}
|
||||
return arr[l];
|
||||
}
|
||||
|
||||
// 返回左右范围
|
||||
private static int[] partition(int[] arr, int l, int r, int pivot) {
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,144 @@
|
|||
package com.learn.learn.tixi.twentieth;
|
||||
|
||||
import java.util.HashMap;
|
||||
// https://leetcode.com/problems/stickers-to-spell-word/
|
||||
public class ArrToString {
|
||||
public static int minStickers1(String[] stickers,String target){
|
||||
int ans = process1(stickers,target);
|
||||
return ans==Integer.MAX_VALUE?-1:ans;
|
||||
}
|
||||
|
||||
/*
|
||||
所有贴纸stickers,每一张贴纸都有无穷张
|
||||
target
|
||||
最少张数
|
||||
*/
|
||||
private static int process1(String[] stickers, String target) {
|
||||
if (target.length()==0){
|
||||
return 0;
|
||||
}
|
||||
int min = Integer.MAX_VALUE;
|
||||
// 每张贴纸被剪无数次还剩多少
|
||||
for (String first:stickers){
|
||||
String rest = minus(target,first);
|
||||
if (rest.length()!=target.length()){
|
||||
min=Math.min(min,process1(stickers,rest));
|
||||
}
|
||||
}
|
||||
return min+(min == Integer.MAX_VALUE?0:1);
|
||||
}
|
||||
|
||||
private static String minus(String s1, String s2) {
|
||||
char[] str1 = s1.toCharArray();
|
||||
char[] str2 = s2.toCharArray();
|
||||
int[] count = new int[26];
|
||||
for (char cha:str1){
|
||||
count[cha-'a']++;
|
||||
}
|
||||
for (char cha:str2){
|
||||
count[cha-'a']--;
|
||||
}
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for (int i = 0;i<26;i++){
|
||||
if (count[i]>0){
|
||||
for (int j=0;j<count[i];j++){
|
||||
builder.append((char) (i+'a'));
|
||||
}
|
||||
}
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
public static int minStickers2(String[] stickers,String target){
|
||||
int n = stickers.length;
|
||||
// 关键优化(用词频表替代贴纸数组)
|
||||
int[][]counts = new int[n][26];
|
||||
for (int i = 0;i<n;i++){
|
||||
char[]str=stickers[i].toCharArray();
|
||||
for (char cha:str){
|
||||
counts[i][cha-'a']++;
|
||||
}
|
||||
}
|
||||
int ans = process2(counts,target);
|
||||
return ans == Integer.MAX_VALUE?-1:ans;
|
||||
}
|
||||
// stickers[i] 数组,当初i号贴纸的字符统计 int[][] stickers ->所有的贴纸
|
||||
// 每一种贴纸都有无穷张
|
||||
// 返回搞定target的最少张数
|
||||
public static int process2(int[][] stickers,String t){
|
||||
if (t.length()==0){
|
||||
return 0;
|
||||
}
|
||||
char[] target=t.toCharArray();
|
||||
int[] tcounts= new int[26];
|
||||
for (char cha:target){
|
||||
tcounts[cha-'a']++;
|
||||
}
|
||||
int n = stickers.length;
|
||||
int min = Integer.MAX_VALUE;
|
||||
for (int i = 0;i<n;i++){
|
||||
int[] sticker = stickers[i];
|
||||
// 最关键优化(重要剪枝,这一步也很贪心)
|
||||
if (sticker[target[0]-'a']>0){
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for (int j=0;j<26;j++){
|
||||
if (tcounts[j]>0){
|
||||
int nums = tcounts[j]-sticker[j];
|
||||
for (int k = 0;k<nums;k++){
|
||||
builder.append((char)(j+'a'));
|
||||
}
|
||||
}
|
||||
}
|
||||
String rest = builder.toString();
|
||||
min = Math.min(min,process2(stickers,rest));
|
||||
}
|
||||
}
|
||||
return min + (min == Integer.MAX_VALUE?0:1);
|
||||
}
|
||||
public static int minStickers3(String [] stickers,String target){
|
||||
int n=stickers.length;
|
||||
int[][] counts = new int[n][26];
|
||||
for (int i = 0;i<n;i++){
|
||||
char[] str = stickers[i].toCharArray();
|
||||
for (char cha:str){
|
||||
counts[i][cha-'a']++;
|
||||
}
|
||||
}
|
||||
HashMap<String,Integer> dp = new HashMap<>();
|
||||
dp.put("",0);
|
||||
int ans = process3(counts,target,dp);
|
||||
return ans == Integer.MAX_VALUE?-1:ans;
|
||||
}
|
||||
|
||||
private static int process3(int[][] stickers, String t, HashMap<String, Integer> dp) {
|
||||
if (dp.containsKey(t)){
|
||||
return dp.get(t);
|
||||
}
|
||||
char[] target = t.toCharArray();
|
||||
int[] tcounts = new int[26];
|
||||
for (char cha:target){
|
||||
tcounts[cha-'a']++;
|
||||
}
|
||||
int n=stickers.length;
|
||||
int min = Integer.MAX_VALUE;
|
||||
for (int i=0;i<n;i++){
|
||||
int[] sticker = stickers[i];
|
||||
if (sticker[target[0]-'a']>0){
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for (int j= 0 ;j<26;j++){
|
||||
if (tcounts[j]>0){
|
||||
int nums= tcounts[j]-sticker[j];
|
||||
for (int k=0;k<nums;k++){
|
||||
builder.append((char)(j+'a'));
|
||||
}
|
||||
}
|
||||
}
|
||||
String rest = builder.toString();
|
||||
min = Math.min(min,process3(stickers,rest,dp));
|
||||
}
|
||||
}
|
||||
int ans = min+(min==Integer.MAX_VALUE?0:1);
|
||||
dp.put(t,ans);
|
||||
return ans;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
package com.learn.learn.tixi.twentieth;
|
||||
|
||||
public class BagMaxValue {
|
||||
public static void main(String[] args) {
|
||||
int [] weight = {3,2,4,7,3,1,7};
|
||||
int [] value = {5,6,3,19,12,4,2};
|
||||
int bag = 15;
|
||||
System.out.println(maxValue(weight,value,bag));
|
||||
System.out.println(dp(weight,value,bag));
|
||||
}
|
||||
//====================================暴力递归
|
||||
public static int maxValue(int[] w,int[] v,int bag){
|
||||
if (w==null||w.length==0||v==null||v.length==0){
|
||||
return 0;
|
||||
}
|
||||
return process(w,v,0,bag);
|
||||
}
|
||||
/*
|
||||
要与不要都测试
|
||||
*/
|
||||
public static int process(int[] w,int[] v,int index,int bag){
|
||||
if (bag<0){
|
||||
// 设置无效解
|
||||
return -1;
|
||||
}
|
||||
if (index == w.length-1){
|
||||
return 0;
|
||||
}
|
||||
// 有货,bag有空间
|
||||
// 不要当前货
|
||||
int p1 = process(w,v,index+1,bag);
|
||||
int next = process(w, v, index + 1, bag - w[index]);
|
||||
int p2 =0 ;
|
||||
if (next!=-1){
|
||||
p2 = v[index]+next;
|
||||
}
|
||||
return Math.max(p1,p2);
|
||||
|
||||
}
|
||||
//========================================缓存
|
||||
// 尝试策略就是动态规划转移方程。
|
||||
// 动态规划转移方程就是尝试策略。
|
||||
public static int dp(int[] w,int[] v,int bag){
|
||||
if (w==null||w.length==0||v==null||v.length==0){
|
||||
return 0;
|
||||
}
|
||||
int n = w.length;
|
||||
int [][] dp = new int[n+1][bag+1];
|
||||
for (int index = n-1;index>=0;index--){
|
||||
for (int rest = 0;rest<=bag;rest++){
|
||||
int p1 = dp[index+1][rest];
|
||||
int p2=0;
|
||||
int next = rest-w[index]<0?-1:dp[index+1][rest-w[index]];
|
||||
if (next!=-1){
|
||||
p2 = v[index]+next;
|
||||
}
|
||||
dp[index][rest]=Math.max(p1,p2);
|
||||
}
|
||||
}
|
||||
|
||||
return dp[0][bag];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
package com.learn.learn.tixi.twentieth;
|
||||
// https://leetcode.cn/problems/longest-common-subsequence/
|
||||
public class LongestCommonSubsequence {
|
||||
|
||||
public static int longestCommonSubsequence(String s1,String s2){
|
||||
if (s1==null||s2==null||s1.length()==0||s2.length()==0){
|
||||
return 0;
|
||||
}
|
||||
char[] str1 = s1.toCharArray();
|
||||
char[] str2 = s2.toCharArray();
|
||||
return process1(str1,str2,str1.length-1,str2.length-1);
|
||||
}
|
||||
public static int process1(char[] str1,char[] str2,int i,int j){
|
||||
if (i==0&&j==0){
|
||||
return str1[i]==str2[j]?1:0;
|
||||
}else if (i==0){
|
||||
if (str2[j]==str1[i]){
|
||||
return 1;
|
||||
}else {
|
||||
process1(str1,str2,i,j-1);
|
||||
}
|
||||
}else if (j==0){
|
||||
if (str2[j]==str1[i]){
|
||||
return 1;
|
||||
}else {
|
||||
process1(str1,str2,i-1,j);
|
||||
}
|
||||
}else {
|
||||
// 样本对应,结尾该如何组织可能性
|
||||
// 不以i结尾可能以j结尾,
|
||||
int p1 = process1(str1,str2,i-1,j);
|
||||
// 即以i结尾也不以j结尾,
|
||||
int p2 = process1(str1,str2,i,j-1);
|
||||
// 即以i结尾又以j结尾
|
||||
int p3 = str1[i]==str2[j]?(1+process1(str1,str2,i-1,j-1)):0;
|
||||
return Math.max(p1,Math.max(p2,p3));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static int longestCommonSubsequence2(String s1,String s2){
|
||||
if (s1==null||s2==null||s1.length()==0||s2.length()==0){
|
||||
return 0;
|
||||
}
|
||||
char[] str1 = s1.toCharArray();
|
||||
char[] str2 = s2.toCharArray();
|
||||
int n= str1.length;
|
||||
int m = str2.length;
|
||||
int [][] dp = new int[n][m];
|
||||
dp[0][0]=str1[0]==str2[0]?1:0;
|
||||
for (int j=1;j<m;j++){
|
||||
dp[0][j]=str1[0]==str2[j]?1:dp[0][j-1];
|
||||
}
|
||||
for (int i=1;i<n;i++){
|
||||
dp[i][0]=str1[i]==str2[0]?1:dp[i-1][0];
|
||||
}
|
||||
for (int i=1;i<n;i++){
|
||||
for (int j=1;j<m;j++){
|
||||
int p1 = dp[i-1][j];
|
||||
// 即以i结尾也不以j结尾,
|
||||
int p2 = dp[i][j-1];
|
||||
// 即以i结尾又以j结尾
|
||||
int p3 = str1[i]==str2[j]?(1+dp[i-1][j-1]):0;
|
||||
dp[i][j]= Math.max(p1,Math.max(p2,p3));
|
||||
}
|
||||
}
|
||||
return dp[n-1][m-1];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
package com.learn.learn.tixi.twentieth;
|
||||
|
||||
import org.apache.tomcat.util.buf.StringUtils;
|
||||
|
||||
public class NumberConvert {
|
||||
public static void main(String[] args) {
|
||||
System.out.println(number("111"));
|
||||
System.out.println(dp("111"));
|
||||
System.out.println(number("305"));
|
||||
System.out.println(dp("305"));
|
||||
}
|
||||
public static int number(String str){
|
||||
if (str==null||str.length()==0){
|
||||
return 0;
|
||||
}
|
||||
return process(str.toCharArray(),0);
|
||||
}
|
||||
|
||||
/*
|
||||
从0开始看有多少中转换方式
|
||||
*/
|
||||
private static int process(char[] str, int i) {
|
||||
if (i==str.length){
|
||||
// 之前的转换方式
|
||||
return 1;
|
||||
}
|
||||
if (str[i]=='0'){//之前决定有问题
|
||||
return 0;
|
||||
}
|
||||
// i 位置单转
|
||||
int ways = process(str,i+1);
|
||||
if(i+1<str.length&&(str[i]-'0')*10+str[i+1]-'0'<27){
|
||||
ways +=process(str,i+2);
|
||||
}
|
||||
return ways;
|
||||
}
|
||||
|
||||
//===================================缓存
|
||||
public static int dp(String str){
|
||||
if (str==null||str.length()==0){
|
||||
return 0;
|
||||
}
|
||||
char[] strChar = str.toCharArray();
|
||||
int n = strChar.length;
|
||||
int[] dp = new int[n+1];
|
||||
// 依赖后面的位置,从右往左填写
|
||||
dp[n]=1;
|
||||
for (int i=n-1;i>=0;i--){
|
||||
if (strChar[i]!='0'){
|
||||
int ways=dp[i+1];
|
||||
if (i + 1 < strChar.length &&(strChar[i]-'0')*10+strChar[i+1]-'0'<27) {
|
||||
ways+=dp[i+2];
|
||||
}
|
||||
dp[i]=ways;
|
||||
}
|
||||
}
|
||||
return dp[0];
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
package com.learn.learn.tixi.twenty.ninth;
|
||||
|
||||
/**
|
||||
* @ClassName Manacher
|
||||
* @Description
|
||||
* @Author shixiaohua
|
||||
* @Date 2022-07-15 22:20
|
||||
**/
|
||||
public class Manacher {
|
||||
public static int manacher(String s){
|
||||
if (s==null||s.length()==0){
|
||||
return 0;
|
||||
}
|
||||
// 121aaaa2323aa -> #1#2#1#a#a#a#a#2#3#2#3#a#a#
|
||||
char[] str = manacherString(s);
|
||||
// 回文半径大小
|
||||
int[] pArr = new int[str.length];
|
||||
int c = -1;
|
||||
// 讲述中:R代表最右的扩成功位置.coding :最右的扩成功的位置的,再下一个位置
|
||||
int r = -1;
|
||||
int max = Integer.MIN_VALUE;
|
||||
for (int i =0;i<str.length;i++){
|
||||
// r第一个违规的位置,i>=r
|
||||
// i位置扩出来的答案,i位置扩的区域,至少是多大.
|
||||
|
||||
// 如果i在r外,至少回文半径1
|
||||
// 如果i在r内,如果i`在LR内在回文为i=i`
|
||||
// 如果i在r内,如果i`在LR外在回文为i=r
|
||||
// 如果i在r内,如果i`压线i->r=(i`)
|
||||
// 2*c-i = i`
|
||||
// 那个区域不用校验
|
||||
pArr[i]=r>i?Math.min(pArr[2*c-i],r-i):1;
|
||||
// 新的校验
|
||||
while (i+pArr[i]<str.length&&i-pArr[i]>-1){
|
||||
if (str[i+pArr[i]]==str[i-pArr[i]]){
|
||||
pArr[i]++;
|
||||
}else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i+pArr[i]>r){
|
||||
r=i+pArr[i];
|
||||
c=i;
|
||||
}
|
||||
max = Math.max(max,pArr[i]);
|
||||
}
|
||||
// 121 #1#2#1# 4-1
|
||||
// 1221 #1#2#2#1# 5-1
|
||||
return max-1;
|
||||
}
|
||||
|
||||
private static char[] manacherString(String s) {
|
||||
return s.toCharArray();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
package com.learn.learn.tixi.twenty.seven;
|
||||
|
||||
/**
|
||||
* @ClassName KMP
|
||||
* @Description
|
||||
* @Author shixiaohua
|
||||
* @Date 2022-07-14 22:38
|
||||
**/
|
||||
public class KMP {
|
||||
public static int getIndexOf(String s1,String s2){
|
||||
if (s1==null||s2==null||s2.length()<1||s1.length()<s2.length()){
|
||||
return -1;
|
||||
}
|
||||
char[] str1 = s1.toCharArray();
|
||||
char[] str2 = s2.toCharArray();
|
||||
int x=0;
|
||||
int y=0;
|
||||
int[] next = getNextArray(str2);
|
||||
while (x<str1.length&&y<str2.length){
|
||||
if (str1[x]==str2[y]){
|
||||
x++;
|
||||
y++;
|
||||
}else if (next[y]==-1){
|
||||
x++;
|
||||
}else {
|
||||
y=next[y];
|
||||
}
|
||||
}
|
||||
return y==str2.length?x-y:-1;
|
||||
}
|
||||
|
||||
private static int[] getNextArray(char[] str2) {
|
||||
if (str2.length==1){
|
||||
return new int[]{-1};
|
||||
}
|
||||
int[] next = new int[str2.length];
|
||||
next[0]=-1;
|
||||
next[1]=0;
|
||||
int i=2;// 目前位置上求next数组的值
|
||||
int cn=0;
|
||||
// 不同往前跳.
|
||||
while (i<next.length){
|
||||
if (str2[i-1]==str2[cn]){// 匹配成功加1
|
||||
next[i++]=++cn;
|
||||
}else if (cn>0){
|
||||
// 如果不同跳到前一次记录相同个数的位置比较
|
||||
cn = next[cn];
|
||||
}else {
|
||||
next[i++]=0;
|
||||
}
|
||||
}
|
||||
return next;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
package com.learn.learn.tixi.twentyfirst;
|
||||
|
||||
/**
|
||||
* @ClassName CoffeeWash
|
||||
* @Description
|
||||
* @Author ZhaoLiXian
|
||||
* @Date 2022-06-28 21:29
|
||||
**/
|
||||
public class CoffeeWash {
|
||||
|
||||
public static void main(String[] args) {
|
||||
//bestTime()
|
||||
}
|
||||
// drinks 所有杯子可以开始洗的时间
|
||||
// wash 单杯洗干净的时间(串行)
|
||||
// air 挥发干净的时间(并行)
|
||||
// free 洗的机器什么时候可用
|
||||
// drinks[index...]都变干净,最早的结束时间(返回)
|
||||
public static int bestTime(int[] drinks,int wash,int air,int index,int free){
|
||||
if (index == drinks.length){
|
||||
return 0;
|
||||
}
|
||||
// index 号杯子 决定洗
|
||||
int selfClean1 = Math.max(drinks[index],free)+wash;
|
||||
int restClean1 = bestTime(drinks,wash,air,index+1,selfClean1);
|
||||
int p1 = Math.max(selfClean1,restClean1);
|
||||
// index 号杯子 决定挥发
|
||||
int selfClean2 = drinks[index]+air;
|
||||
int restClean2 = bestTime(drinks,wash,air,index+1,free);
|
||||
int p2=Math.max(selfClean2,restClean2);
|
||||
return Math.min(p1,p2);
|
||||
}
|
||||
|
||||
public static int bestTimeDp(int[] drinks,int wash,int air){
|
||||
int n = drinks.length;
|
||||
int maxFree = 0;
|
||||
for (int i = 0;i<drinks.length;i++){
|
||||
maxFree = Math.max(maxFree,drinks[i])+wash;
|
||||
}
|
||||
int[][] dp = new int[n+1][maxFree+1];
|
||||
for (int index = n-1;index>=0;index --){
|
||||
for (int free = 0;free<=maxFree;free++){
|
||||
int selfClean1 = Math.max(drinks[index],free)+wash;
|
||||
if (selfClean1>maxFree){
|
||||
continue;
|
||||
}
|
||||
int restClean1 = dp[index+1][selfClean1];
|
||||
int p1 = Math.max(selfClean1,restClean1);
|
||||
|
||||
int selfClean2 = drinks[index]+air;
|
||||
int restClean2 = dp[index+1][free];
|
||||
int p2=Math.max(selfClean2,restClean2);
|
||||
dp[index][free]=Math.min(p1,p2);
|
||||
}
|
||||
}
|
||||
return dp[0][0];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
package com.learn.learn.tixi.twentyfirst;
|
||||
|
||||
/**
|
||||
* @ClassName Palindromic
|
||||
* @Description
|
||||
* @Author
|
||||
* @Date 2022-06-26 16:26
|
||||
**/
|
||||
// https://leetcode.cn/problems/longest-palindromic-subsequence/
|
||||
public class Palindromic {
|
||||
public static int lpsl(String s) {
|
||||
if (s == null || s.length() == 0) {
|
||||
return 0;
|
||||
}
|
||||
char[] str = s.toCharArray();
|
||||
return f(str, 0, str.length - 1);
|
||||
}
|
||||
|
||||
public static int f(char[] str, int l, int r) {
|
||||
if (l == r) {
|
||||
return 0;
|
||||
}
|
||||
if (l == r - 1) {
|
||||
return str[l] == str[r] ? 2 : 1;
|
||||
}
|
||||
int p1 = f(str, l + 1, r - 1);
|
||||
int p2 = f(str, l, r - 1);
|
||||
int p3 = f(str, l + 1, r);
|
||||
int p4 = str[l] != str[r] ? 0 : (2 + f(str, l + 1, r - 1));
|
||||
return Math.max(Math.max(p1, p2), Math.max(p3, p4));
|
||||
}
|
||||
|
||||
public static int lpsl2(String s) {
|
||||
if (s == null || s.length() == 0) {
|
||||
return 0;
|
||||
}
|
||||
char[] str = s.toCharArray();
|
||||
int n = str.length;
|
||||
// l 0....n-1
|
||||
// r 0....n-1
|
||||
int[][] dp = new int[n][n];
|
||||
dp[n - 1][n - 1] = 1;
|
||||
for (int i = 0; i < n - 1; i++) {
|
||||
dp[i][i] = 1;
|
||||
dp[i][i + 1] = str[i] == str[i + 1] ? 2 : 1;
|
||||
}
|
||||
// for (int l = n - 3; l >= 0; l--) {
|
||||
// for (int r = l + 2; r < n; r++) {
|
||||
// int p1 = dp[l + 1][r - 1];
|
||||
// int p2 = dp[l][r - 1];
|
||||
// int p3 = dp[l + 1][r];
|
||||
// int p4 = str[l] != str[r] ? 0 : (2 + dp[l + 1][r - 1]);
|
||||
// dp[l][r] = Math.max(Math.max(p1, p2), Math.max(p3, p4));
|
||||
// }
|
||||
// }
|
||||
for (int l = n - 3; l >= 0; l--) {
|
||||
for (int r = l + 2; r < n; r++) {
|
||||
dp[l][r]=Math.max(dp[l][r-1],dp[l+1][r]);
|
||||
if (str[l]==str[r]){
|
||||
dp[l][r]=Math.max(dp[l][r],2+dp[l+1][r-1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return dp[0][n - 1];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
package com.learn.learn.tixi.twentyforth;
|
||||
|
||||
/**
|
||||
* @ClassName NQueens
|
||||
* @Description
|
||||
* @Author ZhaoLiXian
|
||||
* @Date 2022-07-08 20:05
|
||||
**/
|
||||
public class NQueens {
|
||||
public static int num(int n){
|
||||
if (n<1){
|
||||
return 0;
|
||||
}
|
||||
int [] record = new int[n];
|
||||
return process(0,record,n);
|
||||
}
|
||||
|
||||
// 当前来到i行,一共n-1行
|
||||
// 在i行上放皇后,所有列都尝试
|
||||
// 必须要保证跟之前所有的皇后不打架
|
||||
// int[] record record[x]=y 之前的第x行的皇后,放在了y列上
|
||||
// 返回:不关心i以上发生了什么,i...后续有多少合法的方法数
|
||||
private static int process(int i, int[] record, int n) {
|
||||
if (i==n){
|
||||
return 1;
|
||||
}
|
||||
int res = 0;
|
||||
// i行皇后,放哪一列呢? j列
|
||||
for (int j=0;j<n;j++){
|
||||
if (isValid(record,i,j)){
|
||||
record[i]=j;
|
||||
res+=process(i+1,record,n);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
private static boolean isValid(int[] record, int i, int j) {
|
||||
for (int k=0;k<i;k++){
|
||||
if (j==record[k]||Math.abs(record[k]-j)==Math.abs(i-k)){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
package com.learn.learn.tixi.twentyforth;
|
||||
|
||||
/**
|
||||
* @ClassName SplitSumClosed
|
||||
* @Description
|
||||
* @Author shixiaohua
|
||||
* @Date 2022-07-06 19:45
|
||||
**/
|
||||
public class SplitSumClosed {
|
||||
public static int right(int[] arr){
|
||||
if (arr==null||arr.length<2){
|
||||
return 0;
|
||||
}
|
||||
int sum = 0;
|
||||
for (int num :arr){
|
||||
sum+=num;
|
||||
}
|
||||
return process(arr,0,sum>>1);
|
||||
}
|
||||
|
||||
private static int process(int[] arr, int i, int rest) {
|
||||
if (i==arr.length){
|
||||
return 0;
|
||||
}else {
|
||||
int p1=process(arr,i+1,rest);
|
||||
int p2=0;
|
||||
if (arr[i]<=rest){
|
||||
p2=arr[i]+process(arr,i+1,rest-arr[i]);
|
||||
}
|
||||
return Math.max(p1,p2);
|
||||
}
|
||||
}
|
||||
|
||||
public static int db(int [] arr){
|
||||
if (arr==null||arr.length<2){
|
||||
return 0;
|
||||
}
|
||||
int sum = 0;
|
||||
for (int num :arr){
|
||||
sum+=num;
|
||||
}
|
||||
sum /=2;
|
||||
int n=arr.length;
|
||||
int[][] dp = new int[n+1][sum+1];
|
||||
for (int i=n-1;i>=0;i--){
|
||||
for (int rest=0;rest<=sum;rest++){
|
||||
int p1=dp[i+1][rest];
|
||||
int p2=0;
|
||||
if (arr[i]<=rest){
|
||||
p2=arr[i]+dp[i+1][rest-arr[i]];
|
||||
}
|
||||
dp[i][rest]= Math.max(p1,p2);
|
||||
}
|
||||
}
|
||||
return dp[0][sum];
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,92 @@
|
|||
package com.learn.learn.tixi.twentyforth;
|
||||
|
||||
/**
|
||||
* @ClassName SplitSumClosedHalf
|
||||
* @Description
|
||||
* @Author shixiaohua
|
||||
* @Date 2022-07-07 18:57
|
||||
**/
|
||||
public class SplitSumClosedHalf {
|
||||
|
||||
public static int right(int[] arr){
|
||||
if (arr==null||arr.length<2){
|
||||
return 0;
|
||||
}
|
||||
int sum = 0;
|
||||
for (int num :arr){
|
||||
sum+=num;
|
||||
}
|
||||
if ((arr.length&1)==0){
|
||||
return process(arr,0,arr.length/2,sum>>1);
|
||||
}else {
|
||||
return Math.max(process(arr,0,arr.length/2,sum>>1),process(arr,0,arr.length/2+1,sum>>1));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// arr[i....] 自由选择,挑选的个数一定要是picks个,累加和<=rest,离rest最近的返回
|
||||
private static int process(int[] arr, int i, int picks, int rest) {
|
||||
if (i==arr.length){
|
||||
return rest==0?0:-1;
|
||||
}else {
|
||||
int p1=process(arr,i+1,picks,rest);
|
||||
int p2=-1;
|
||||
if (arr[i]<=rest){
|
||||
int next = process(arr,i+1,picks-1,rest-arr[i]);
|
||||
if (next!=-1){
|
||||
p2=arr[i]+next;
|
||||
}
|
||||
}
|
||||
return Math.max(p1,p2);
|
||||
}
|
||||
}
|
||||
|
||||
public static int dp(int [] arr){
|
||||
if (arr==null||arr.length<2){
|
||||
return 0;
|
||||
}
|
||||
int sum = 0;
|
||||
for (int num :arr){
|
||||
sum+=num;
|
||||
}
|
||||
sum/=2;
|
||||
int n = arr.length;
|
||||
int m = (n+1)/2;
|
||||
|
||||
int[][][] dp = new int[n+1][m+1][sum+1];
|
||||
for (int i=0;i<=n+1;i++){
|
||||
for (int j=0;j<=m+1;j++){
|
||||
for (int k=0;k<=sum+1;k++){
|
||||
dp[i][j][k]=-1;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int rest = 0; rest <= sum; rest++) {
|
||||
dp[n][0][rest]=0;
|
||||
}
|
||||
for (int i = n-1;i>=0;i--){
|
||||
for (int picks = 0;picks<=m;picks++){
|
||||
for (int rest = 0;rest<=sum;rest++){
|
||||
int p1=dp[i+1][picks][rest];
|
||||
int p2=-1;
|
||||
if (picks-1>=0 && arr[i]<=rest){
|
||||
int next = dp[i+1][picks-1][rest-arr[i]];
|
||||
if (next!=-1){
|
||||
p2=arr[i]+next;
|
||||
}
|
||||
}
|
||||
dp[i][picks][rest]= Math.max(p1,p2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
if ((arr.length&1)==0){
|
||||
return dp[0][arr.length/2][sum];
|
||||
}else {
|
||||
return Math.max(dp[0][arr.length/2][sum],dp[0][(arr.length/2)+1][sum]);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
package com.learn.learn.tixi.twentysecond;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
|
||||
/**
|
||||
* @ClassName BobDie
|
||||
* @Description
|
||||
* @Author ZhaoLiXian
|
||||
* @Date 2022-07-01 19:44
|
||||
**/
|
||||
public class BobDie {
|
||||
public static double livePosibility1(int row,int col,int k,int n,int m){
|
||||
return (double)process(row,col,k,n,m)/Math.pow(4,k);
|
||||
}
|
||||
|
||||
/**
|
||||
* description: 目前位置,row,col,剩余步数rest,走完获得1个生存点.
|
||||
* date: 2022-07-01 19:51
|
||||
* author: Xiaohua XH4 Shi
|
||||
* @param row
|
||||
* @param col
|
||||
* @param rest
|
||||
* @param n
|
||||
* @param m
|
||||
* @return long
|
||||
*/
|
||||
private static long process(int row, int col, int rest, int n, int m) {
|
||||
// 剪枝
|
||||
if (row<0||row==n||col<0||col==m){
|
||||
return 0;
|
||||
}
|
||||
if (rest ==0){
|
||||
return 1;
|
||||
}
|
||||
long up = process(row-1,col,rest-1,n,m);
|
||||
long down = process(row+1,col,rest-1,n,m);
|
||||
long left = process(row,col-1,rest-1,n,m);
|
||||
long right = process(row,col+1,rest-1,n,m);
|
||||
return up+down+left+right;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
package com.learn.learn.tixi.twentysecond;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @ClassName Money
|
||||
* @Description
|
||||
* @Author ZhaoLiXian
|
||||
* @Date 2022-06-29 22:38
|
||||
**/
|
||||
public class Money {
|
||||
public static class Info{
|
||||
public int[] coins;
|
||||
public int[] zhangs;
|
||||
public Info(int[]coins,int[]zhangs){
|
||||
coins= this.coins;
|
||||
zhangs = this.zhangs;
|
||||
}
|
||||
}
|
||||
// 词频统计
|
||||
public static Info getInfo(int[] arr){
|
||||
HashMap<Integer,Integer> counts = new HashMap<>();
|
||||
for (int value:arr){
|
||||
if (!counts.containsKey(value)){
|
||||
counts.put(value,1);
|
||||
}else {
|
||||
counts.put(value,counts.get(value)+1);
|
||||
}
|
||||
}
|
||||
int n = counts.size();
|
||||
int[] coins = new int[n];
|
||||
int[] zhangs = new int[n];
|
||||
int index = 0;
|
||||
for (Map.Entry<Integer,Integer> entry:counts.entrySet()){
|
||||
coins[index]=entry.getKey();
|
||||
zhangs[index++]=entry.getValue();
|
||||
}
|
||||
return new Info(coins,zhangs);
|
||||
}
|
||||
public static int coinsWay(int[] arr,int aim){
|
||||
if (arr ==null||arr.length==0||aim<0){
|
||||
return 0;
|
||||
}
|
||||
Info info = getInfo(arr);
|
||||
return process(info.coins,info.zhangs,0,aim);
|
||||
}
|
||||
|
||||
private static int process(int[] coins, int[] zhangs, int index, int rest) {
|
||||
if (index == coins.length){
|
||||
return rest ==0?1:0;
|
||||
}
|
||||
int ways = 0;
|
||||
for (int zhang =0;zhang*coins[index]<=rest && zhang<=zhangs[index];zhang++){
|
||||
ways+=process(coins,zhangs,index+1,rest-(zhang*coins[index]));
|
||||
}
|
||||
return ways;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,113 @@
|
|||
package com.learn.learn.tixi.twentythird;
|
||||
|
||||
/**
|
||||
* @ClassName KillMonster
|
||||
* @Description
|
||||
* @Author ZhaoLiXian
|
||||
* @Date 2022-07-01 21:38
|
||||
**/
|
||||
public class KillMonster {
|
||||
public static double killMonster(int n, int m, int k) {
|
||||
if (n < 1 || m < 1 || k < 1) {
|
||||
return 0;
|
||||
}
|
||||
long all = (long) Math.pow(m + 1, k);
|
||||
long kill = process1(100, 9, 10);
|
||||
return (double) ((double) kill / (double) all);
|
||||
}
|
||||
|
||||
// 怪兽还剩N滴血
|
||||
// 每次伤害在[0~M]范围上
|
||||
// 还有K次可以砍
|
||||
// 返回砍死的情况
|
||||
public static long process1(int hp, int m, int time) {
|
||||
if (hp <= 0) {
|
||||
return (long) Math.pow(m + 1, time);
|
||||
}
|
||||
if (time == 0) {
|
||||
return hp <= 0 ? 1 : 0;
|
||||
}
|
||||
long ways = 0;
|
||||
// 从0开始到m等概率
|
||||
for (int i = 0; i <= m; i++) {
|
||||
ways += process1(hp - i, m, time - 1);
|
||||
}
|
||||
return ways;
|
||||
}
|
||||
|
||||
// 可变参数 n,time
|
||||
public static double dp1(int n, int m, int k) {
|
||||
if (n < 1 || m < 1 || k < 1) {
|
||||
return 0;
|
||||
}
|
||||
long all = (long) Math.pow(m + 1, k);
|
||||
// 从0-n长度为n+1
|
||||
long[][] dp = new long[k + 1][n + 1];
|
||||
dp[0][0] = 1;
|
||||
for (int times = 1; times <= k; times++) {
|
||||
dp[times][0] = (long) Math.pow(m + 1, times);
|
||||
for (int hp = 1; hp <= n; hp++) {
|
||||
long ways = 0;
|
||||
for (int i = 0; i <= m; i++) {
|
||||
if (hp - i >= 0) {
|
||||
ways += dp[times - 1][hp - 1];
|
||||
} else {
|
||||
ways += (long) Math.pow(m + 1, times - 1);
|
||||
}
|
||||
}
|
||||
dp[times][hp] = ways;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 看主函数怎么调用的
|
||||
long kill = dp[k][n];
|
||||
return (double) ((double) kill / (double) all);
|
||||
}
|
||||
|
||||
// 枚举行为到依赖关系 可变参数 n,time
|
||||
public static double dp2(int n, int m, int k) {
|
||||
if (n < 1 || m < 1 || k < 1) {
|
||||
return 0;
|
||||
}
|
||||
long all = (long) Math.pow(m + 1, k);
|
||||
// 从0-n长度为n+1
|
||||
long[][] dp = new long[k + 1][n + 1];
|
||||
dp[0][0] = 1;
|
||||
for (int times = 1; times <= k; times++) {
|
||||
dp[times][0] = (long) Math.pow(m + 1, times);
|
||||
for (int hp = 1; hp <= n; hp++) {
|
||||
dp[times][hp] = dp[times][hp - 1] + dp[times - 1][hp];
|
||||
if (hp - 1 - m >= 0) {
|
||||
dp[times][hp] -= dp[times - 1][hp - 1 - m];
|
||||
} else {
|
||||
dp[times][hp] -= (long) Math.pow(m + 1, times - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
// 看主函数怎么调用的
|
||||
long kill = dp[k][n];
|
||||
return (double) ((double) kill / (double) all);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
int nMax = 10;
|
||||
int mMax = 10;
|
||||
int kMax = 10;
|
||||
int testTime = 200;
|
||||
System.out.println("测试开始");
|
||||
for (int i=0;i<testTime;i++){
|
||||
int n= (int)Math.random()*nMax;
|
||||
int m= (int)Math.random()*mMax;
|
||||
int k= (int)Math.random()*kMax;
|
||||
double ans1 = dp1(n,m,k);
|
||||
double ans2= dp2(n,m,k);
|
||||
double ans3= killMonster(n,m,k);
|
||||
if (ans1!=ans2||ans2!=ans3){
|
||||
System.out.println("fail");
|
||||
break;
|
||||
}
|
||||
}
|
||||
System.out.print("end");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
package com.learn.learn.tixi.twentythird;
|
||||
|
||||
/**
|
||||
* @ClassName MinCoinsNoLimit
|
||||
* @Description 从左往右的尝试模型
|
||||
* @Author ZhaoLiXian
|
||||
* @Date 2022-07-02 9:48
|
||||
**/
|
||||
public class MinCoinsNoLimit {
|
||||
public static int minCoins(int[]arr,int aim){
|
||||
return process(arr,0,aim);
|
||||
}
|
||||
// arr[index..]面值,每张面值张数自由选择
|
||||
// 搞出rest正好这么多钱,返回最小张数
|
||||
public static int process(int[] arr,int index,int rest){
|
||||
if (rest<0){
|
||||
return Integer.MAX_VALUE;
|
||||
}
|
||||
if (index == arr.length){
|
||||
return rest==0?0:Integer.MAX_VALUE;
|
||||
}else {
|
||||
int ans = Integer.MAX_VALUE;
|
||||
for (int zhang = 0;zhang*arr[index]<=rest;zhang++){
|
||||
int next = process(arr,index+1,rest-zhang*arr[index]);
|
||||
if (next!=Integer.MAX_VALUE){
|
||||
ans = Math.min(ans,zhang+next);
|
||||
}
|
||||
}
|
||||
return ans;
|
||||
}
|
||||
}
|
||||
public static int dp1(int[] arr,int aim){
|
||||
if (aim == 0){
|
||||
return 0;
|
||||
}
|
||||
int n= arr.length;
|
||||
int[][] dp = new int[n+1][aim+1];
|
||||
dp[n][0] =0;
|
||||
for (int j=1;j<=aim;j++){
|
||||
dp[n][j]=Integer.MAX_VALUE;
|
||||
}
|
||||
for (int index = n-1;index>=0;index--){
|
||||
for (int rest = 0;rest<=aim;rest++){
|
||||
int ans = Integer.MAX_VALUE;
|
||||
for (int zhang = 0;zhang*arr[index]<=rest;zhang ++){
|
||||
int next = dp[index+1][rest-zhang*arr[index]];
|
||||
if (next!=Integer.MAX_VALUE){
|
||||
ans = Math.min(ans,zhang+next);
|
||||
}
|
||||
}
|
||||
dp[index][rest]=ans;
|
||||
}
|
||||
}
|
||||
return dp[0][aim];
|
||||
}
|
||||
public static int dp2(int [] arr,int aim){
|
||||
if (aim==0){
|
||||
return 0;
|
||||
}
|
||||
int n = arr.length;
|
||||
int[][] dp = new int[n+1][aim+1];
|
||||
dp[n][0] = 0;
|
||||
for (int j=1;j<=aim;j++){
|
||||
dp[n][j]=Integer.MAX_VALUE;
|
||||
}
|
||||
for (int index=n-1;index>=0;index--){
|
||||
for (int rest = 0;rest<=aim;rest++){
|
||||
dp[index][rest]= dp[index+1][rest];
|
||||
if (rest-arr[index]>=0
|
||||
&& dp[index][rest-arr[index]]!=Integer.MAX_VALUE){
|
||||
dp[index][rest]=Math.min(dp[index][rest],dp[index][rest-arr[index]]+1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return dp[0][aim];
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
|
|
@ -0,0 +1,15 @@
|
|||
package com.learn.learn;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
|
||||
@SpringBootTest
|
||||
class LearnApplicationTests {
|
||||
// 小和问题,数组每个元素左边比他小的数和,最后总体相加
|
||||
// merge sort
|
||||
// 左侧排序,左组小加和。
|
||||
@Test
|
||||
void contextLoads() {
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
快慢指针.
|
||||
|
||||
回文
|
||||
|
||||
面试
|
||||
1. 链表遍历与弹栈.
|
||||
笔试
|
||||
2. 修改右边指针往回指,分别从左右 开始遍历查看是否相同.
|
|
@ -0,0 +1,8 @@
|
|||
单链表环问题.
|
||||
## 二叉树
|
||||
### 先序
|
||||
头左右
|
||||
### 中序
|
||||
左头右
|
||||
### 后续
|
||||
左右头
|
|
@ -0,0 +1,9 @@
|
|||
## 用队列栈实现宽度优先遍历
|
||||
1. 队列弹出一个car并打印
|
||||
2. car有左入左,有右入右.
|
||||
## 用栈实现深度优先遍历.
|
||||
1. 栈中弹出一个car并打印.
|
||||
2. 有右入右,有做入左.
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
从一个节点开始,叶子节点都要,称作子树,否则称作拓扑.
|
||||
|
||||
### 二叉树递归套路
|
||||
1. 假设以x节点为头,假设可以向x左树和x右树要任何信息
|
||||
2. 在上一步的假设下,讨论以x为头节点的数,得到答案的可能性
|
||||
3. 列出所有可能性后,确定到底需要向左树和右树要什么样的信息
|
||||
4. 把左树信息和右树信息求全集,就是任何一颗子树都需要返回的信息S
|
||||
5. 递归函数返回S,每一颗子树都这么要求
|
||||
6. 写代码,在代码中考虑如何把左树信息和右树信息整合出整课数的信息
|
||||
|
||||
|
||||
|
||||
1. 思想边界提醒
|
||||
2. 代码模板化
|
|
@ -0,0 +1,2 @@
|
|||
理清楚问题,在做..declare问题.
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
并查集:两个是否是同一个,两个联合。
|
||||
往上到不能再往上,找父类.
|
||||
并查集扫雷,感染并查集。
|
||||
|
||||
先写整体逻辑后分开写各各子实现。
|
|
@ -0,0 +1,7 @@
|
|||
### 暴力递归
|
||||
1. 把问题转换为规模缩小了的同类问题的子问题.
|
||||
2. 有明确的不需要继续进行递归的条件
|
||||
3. 有当得到了子问题的结果之后的决策过程
|
||||
4. 不记录每一个子问题的解.
|
||||
|
||||
恢复现场
|
|
@ -0,0 +1,9 @@
|
|||
记忆化搜索
|
||||
尝试策略,状态转移
|
||||
|
||||
自然智慧
|
||||
|
||||
### 问题1
|
||||
|
||||
给定一个整型数组arr,代表数值不同的纸牌排成一条线,玩家A和玩家B依次拿走每张纸牌,规定玩家A先拿,玩家B后拿,但是每个玩家每次只能拿走最左边或者最右边的纸牌,玩家A和玩家B都绝顶聪明,请返回最后获胜者的分数。[50,100,20,10]
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
# 认识复杂度、对数器、二分法或异运算
|
||||
1. 时间复杂度
|
||||
2. 额外空间复杂度
|
||||
3. 常数项,一个操作的执行时间不以具体样本量为转移(数组寻址),每次执行时间都是固定的时间。
|
||||
### 时间复杂度
|
||||
#### 选择排序
|
||||
1. n*(看+比)+1
|
||||
2. (n-1)* n*(看+比)+1
|
||||
3. (n-2)* n*(看+比)+1
|
||||
4. 2*(n+n-1+n-2+····+1)+n 看+比 2
|
||||
5. 2an平方+bn+n+c
|
||||
6. 2an平方
|
||||
最高阶,选出最小的,从头开始放。
|
||||
#### 冒泡排序
|
||||
1. 相邻的两个比较,大的放后面,最大值在后面。
|
||||
2. n-1
|
||||
3. n-2
|
||||
4. n-3
|
||||
5. 1
|
||||
5. n平方
|
||||
#### 插入排序
|
||||
1. 最好n
|
||||
2. 最差n平方
|
||||
#### 计算时间复杂度
|
||||
1. 按照最坏的情况来
|
||||
2. 拆分为一个个基本动作
|
||||
3. 如果数据量为n,看基本动作和n之间的关系。
|
||||
4. 只把高阶项留下,低阶项和常数项去除。
|
||||
### 常数项
|
||||
### 最优解
|
||||
1. 时间复杂度
|
||||
2. 空间复杂度
|
||||
#### 常数时间操作
|
||||
1. 常见算数操作
|
||||
2. 移位、位运算
|
||||
3. 复制、比较、自增、自减操作
|
||||
4. 数组寻址操作
|
||||
#### 非常数时间操作
|
||||
1、链表LinkedList
|
||||
### 对数器
|
||||
### 局部最小值
|
||||
数据状况和问题本身梳理问题。
|
||||
二分排他性
|
||||
俩边开始找,根据趋势,二分处理。
|
|
@ -0,0 +1,27 @@
|
|||
### 背包问题
|
||||
重量数组w[]
|
||||
价值数据v[]
|
||||
bag maxvalue int
|
||||
自由挑选货物,让背包里装的货物最多
|
||||
|
||||
### 数字对应
|
||||
规定1对应A,2对应B,3对应C,·····,26对应Z,
|
||||
那么一个数字字符串比如‘111’就可以转换为‘AAA’,‘KA’和‘AK’
|
||||
给定一个只有数字字符串组成的字符串str,返回对少中转换结果
|
||||
### 数组转字符串
|
||||
给定一个字符串str,给定一个字符串类型的数组arr,
|
||||
出现的字符都是小写英文arr每一个字符串,代表一张贴纸,
|
||||
你可以把当个字符剪开使用,目的是拼出来str来返回需要至少
|
||||
多少贴纸可以完成任务。
|
||||
例子:str="babac",arr={"ba","c","abcd"}
|
||||
至少需要两张贴纸"ba"和"abcd",因为使用这两张贴纸,
|
||||
把每一个字符串单独剪开,含有2个a、2个b、1个c。是可以
|
||||
拼出str的。所以返回2
|
||||
### 最长公共子序列
|
||||
样本对应模型:
|
||||
|
||||
### 模型
|
||||
1. 从左往右尝试,要不要判断
|
||||
2. 范围尝试,开头和结尾
|
||||
3. 样本对应模型,结尾
|
||||
4. 业务限制模型
|
|
@ -0,0 +1,14 @@
|
|||
### 回文
|
||||
给定一个字符串str,返回这个字符串的最长回文子序列(不连续,子串连续)长度
|
||||
比如:str="a12b3c43def2ghi1kpm"
|
||||
最长回文子序列是"1234321或者"123c321",返回长度7
|
||||
生成str的逆序串,两个最长的公共子序列就是所求结果.
|
||||
|
||||
|
||||
### 咖啡机
|
||||
给定一个数组arr,arr[i]代表第i号咖啡机泡一杯咖啡的时间
|
||||
给定一个正数N,表示N个人等着咖啡机泡咖啡,每台咖啡机只能轮流泡咖啡
|
||||
只有一台咖啡机,一次只能洗一个杯子,时间耗费a,洗完才能洗下一杯
|
||||
每个咖啡杯也可以自己挥发干净,时间耗费b,咖啡杯可以并行挥发假设所有人拿到
|
||||
咖啡之后立即喝干净,返回从开始等到所有咖啡机变干净的最短时间
|
||||
三个参数:int[]arr,in N,int a,int b
|
|
@ -0,0 +1,25 @@
|
|||
空间压缩技巧
|
||||
|
||||
给定一个二维数组matrix,一个人必须从左上角出发,最后到达有下角沿途只可以向下或者向右走,沿途的数字都累加就是距离
|
||||
累加和返回最小距离累加和.
|
||||
|
||||
arr是货币数组,其中的值都是正数,再给定一个整数aim
|
||||
每个值都认为是一张货币
|
||||
即便是值相同的货币也认为每一张都是不同的,
|
||||
返回组成aim的方法数
|
||||
例如:arr={1,1,1},aim = 2;
|
||||
第0个和第1个能组成2,第1个和第2个能组成2,第0个和第二个能组成2
|
||||
一共就3种方法,所以返回3.
|
||||
|
||||
记忆化搜索,严格表结构
|
||||
|
||||
## 题目四
|
||||
arr是货币数组,其中的值都是正数,再给定一个正数aim.
|
||||
每个值都认为是一张货币
|
||||
认为值相同的货币没有任何不同,
|
||||
返回组成aim的方法数
|
||||
例如arr={1,2,1,1,2,1,2},aim = 4
|
||||
方法:1+1+1+1,1+1+2,2+2
|
||||
一共有三种方法返回3
|
||||
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
枚举行为到依赖关系(依赖下一步),斜率优化.
|
||||
|
||||
arr是面值数组,其中的值都是正数且没有重复.再给定一个正数aim.每个值都认为是一种面值,
|
||||
且认为张数是无限的.返回组成aim的最小货币数
|
|
@ -0,0 +1,65 @@
|
|||
给定一个正整数数组arr,请把arr中所有的数分成两个集合,尽量让两个集合的累加和接近.
|
||||
返回:最接近的情况下,较小集合的累加和.
|
||||
|
||||
|
||||
|
||||
给定一个正整数数组arr,请把arr中所有的数分成两个集合,
|
||||
如果arr长度为偶数,两个集合包含数的个数要一样多,
|
||||
如果arr长度为奇数,两个集合包含数的个数必须只差一个
|
||||
请尽量让两个集合的累加和接近
|
||||
返回:
|
||||
最接近的情况下,较小集合的累加和
|
||||
|
||||
|
||||
|
||||
## 总结
|
||||
什么暴力递归可以继续优化?
|
||||
有重复调用同一个子问题的解,这种递归可以优化
|
||||
如果每一个子问题都是不同的解,无法优化也不用优化.
|
||||
|
||||
暴力递归和动态规划的关系:某一个暴力递归,有解的重复调用,就可以把这个暴力递归优化成动态规划
|
||||
任何动态规划问题,都一定对应着某一个有重复过程的暴力递归
|
||||
但不是所有的暴力递归,都一定对应着动态规划.
|
||||
|
||||
面试题和动态规划的关系
|
||||
解决一个问题,可能有很多尝试方法
|
||||
可能在很多尝试方法中,又有若干个尝试方法有动态规划的方式
|
||||
一个问题可能有若干种动态规划的解法.
|
||||
|
||||
如何找到某个问题的动态规划方式
|
||||
设计暴力递归:重要原则+4中常见尝试模型!重点!
|
||||
分析有没有重复解:套路解决
|
||||
用记忆搜索(缓存,搜索o1就是最优解否则表依赖)->用严格表结构实现动态规划:套路解决
|
||||
看看能否继续优化:套路解决
|
||||
|
||||
面试中暴力递归过程的原则
|
||||
1. 每一个可变参数的类型,一定不要比int类型更加复杂
|
||||
2. 原则1.可以违反,让类型突破到一维线性结构,那必须是单一可变参数
|
||||
3. 如果发现原则1.被违反,但不违反原则2.,只需要做记忆搜索即可
|
||||
4. 可变参数的个数,能少则少.
|
||||
|
||||
知道了面试中设计暴力递归过程的原则,然后呢
|
||||
一定要逼自己找到不违反原则情况下的暴力尝试
|
||||
如果你找到暴力尝试,不符合原则,马上舍弃,找新的.
|
||||
如果某个题目突破了设计原则,一定极难极难,面试中的概率低于5%
|
||||
|
||||
暴力递归到动态规划的套路
|
||||
1. 你已经有了一个不违反原则的暴力递归,而且的确存在解的重复调用
|
||||
2. 找到那些参数的变化会影响返回值,对每一个列出变化范围
|
||||
3. 参数间的所有组合数量,意味着表大小
|
||||
4. 记忆化搜索的方法就是傻缓存,非常容易得到
|
||||
5. 规定好严格表的大小,分析位置的依赖顺序,然后从基础填写到最终解
|
||||
6. 对于有枚举行为的决策过程,进一步优化.
|
||||
|
||||
动态规划的进一步优化
|
||||
1. 空间压缩
|
||||
2. 状态化简
|
||||
3. 四边形不等式
|
||||
4. 其他优化技巧
|
||||
|
||||
## N皇后问题
|
||||
在N*N的棋盘上要摆N个皇后,要求任何两个皇后不同行,不同列,也不在同一条斜线上
|
||||
给定一个整数n,返回n皇后的摆法有多少种.
|
||||
n=1 返回1
|
||||
n=2或3,2皇后和3皇后无论怎么摆都不行,返回0
|
||||
n=8,返回92
|
|
@ -0,0 +1,31 @@
|
|||
逻辑能力
|
||||
|
||||
题目一
|
||||
假设一个固定大小为W的窗口,一次划过arr,
|
||||
返回每一次滑出状况的最大值
|
||||
例如,arr=[4,3,5,4,3,3,6,7],W=3
|
||||
返回:[5,5,5,4,6,7]
|
||||
|
||||
题目二
|
||||
给定一个整型数组arr,和一个整数num
|
||||
某个arr中的子数组sub,如果想达标,必须满足:
|
||||
sub中最大值-sub中最小值<=num
|
||||
返回arr中达标子数组的数量.
|
||||
|
||||
题目三
|
||||
汽车从那几个位置逆时针走能加满油
|
||||
gas [1,1,3,1]
|
||||
cost [2,2,1,1]
|
||||
自己整理个数组,最终和为0表示能跑完 [-1,-1,2,0]
|
||||
累加和,计算最终结果大于0 [-1,-2,0,0,-1,-3,-3,-3]
|
||||
|
||||
题目四
|
||||
arr是货币数组,其中的值都是正数,在给定一个正数aim
|
||||
每个值都认为是一张货币
|
||||
返回组成aim的最少货币数
|
||||
注意:
|
||||
因为是求最少货币数,所以每一张货币认为是相同或者不同都不重要了.
|
||||
|
||||
|
||||
枚举行为用邻近位置代替.
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
一个数组,输出每个位置,左侧第一个比他小的位置,右侧第一个比他小的数.
|
||||
放入从小到大的栈中,相同放到一个数据放入栈中,每次弹出是结算.
|
||||
|
||||
题目一 给定一个只包含正数的数组arr,arr中任何一个子数组sub,一定都可以算出(sub累加和)*(sub中的最小值)是什么,
|
||||
那么所有子数组中,这个值最大是多少.
|
||||
|
||||
以每一个位置做最小值,计算数据
|
||||
|
||||
第一行为底,转直方图,转单调栈.第二行为底第一行为顶计算
|
||||
|
||||
题目五
|
||||
给定以个二维数组matrix,其中的值不是0就是1,返回全部由1组成的子矩形数量.
|
|
@ -0,0 +1,36 @@
|
|||
求裴波那契数列矩阵乘法的方法
|
||||
1)裴波那契数列的线性求解(O(N))的方式求解非常好理解
|
||||
2)利用线性代数,也可以改写另一种表示
|
||||
|F(N),F(N-1)|=|F(2),F(1)|*某个二阶矩阵的N-2次方
|
||||
3)求出这个二阶矩阵,进而最快求出这个二阶矩阵的N-2次方.
|
||||
|
||||
|
||||
题目四
|
||||
第一年农场有1只成熟的母牛A,往后的每年:
|
||||
1)每一只成熟的母牛都会生一只母牛
|
||||
2)每一只新出生的母牛都在出生的第三年成熟
|
||||
3)每一只母牛永远不会死
|
||||
返回n年后的数量.F(n)=F(n-1)+F(n-3)
|
||||
|a b c|
|
||||
|4 3 2|=|3 2 1|* |d e f|
|
||||
|g h i|
|
||||
|
||||
3a+2d+1g = 4
|
||||
3b+2e+1h = 3
|
||||
3c+2f+1i = 2
|
||||
|
||||
|
||||
|a b c|
|
||||
|6 4 3|=|4 3 2|* |d e f|
|
||||
|g h i|
|
||||
|
||||
4a+3d+2g = 6
|
||||
4b+3e+2h = 4
|
||||
4c+3f+2i = 3
|
||||
|
||||
|
||||
n-3
|
||||
|
||||
题目五
|
||||
给定一个数N,想象
|
||||
F(n)=F(n-1)+f(n-2)
|
|
@ -0,0 +1,4 @@
|
|||
KMP算法(全称Knuth-Morris-Pratt字符串查找算法,由三位发明者的姓氏命名)是可以在文本串s中快速查找模式串p的一种算法。
|
||||
|
||||
求解next数组匹配加速.
|
||||
next数组比对往右跳.
|
|
@ -0,0 +1,11 @@
|
|||
求回文子串(连续)
|
||||
|
||||
121aaaa2323aa
|
||||
1. 数字两边插入数值 #1#2#1#a#a#a#a#2#3#2#3#a#a#
|
||||
回文半径/直径,回文半径数组,最右回文边界,取的最右回文边界的中心
|
||||
|
||||
|
||||
1. 如果i在R外,暴力扩
|
||||
2. 如果i在R内,i`在L R内 O(1)
|
||||
i`在L R外 O(1)
|
||||
i`在L压线
|
|
@ -0,0 +1,3 @@
|
|||
## 异或运算
|
||||
无进位相加,满足结合律和交换率
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
在无序数组中求第K小的数
|
||||
1. 改写快排的方法
|
||||
2. bfprt算法
|
||||
|
||||
|
||||
1)随机选p
|
||||
2)分区<p,=p,>p
|
||||
3)命中返回,未命中,选左边或者右边.
|
||||
|
||||
题目
|
||||
给定一个无序数组arr中,给定一个正数k,返回top k个最大的数不同时间复杂度三个方法:
|
||||
1) o(N*logN)
|
||||
2) o(N+K*logN)
|
||||
3) o(N+K*logK)
|
||||
|
||||
蓄水池算法
|
||||
等概率进袋子.
|
|
@ -0,0 +1,11 @@
|
|||
Morris遍历细节
|
||||
假设来到当前节点cur,开始时cur来到头结点的位置
|
||||
1) 如果cur没有左孩子,cur向右移动(cur=cur.right)
|
||||
2) 如果cur有左孩子,找到左子树上最右的节点mostRight:
|
||||
a. 如果mostRight的右指针指向空,让其指向cur,然后cur向左移动(cur=cur.left)
|
||||
b. 如果mostRight的右指针指向cur,让其指向null,然后cur向右移动(cur = cur.right)
|
||||
3) cur为空时停止遍历
|
||||
|
||||
|
||||
|
||||
需要左右树信息强整合则必须二叉树递归套路,否则,可以用Morris遍历.
|
|
@ -0,0 +1,8 @@
|
|||
i
|
||||
父i/2
|
||||
左2*i
|
||||
右2*i+1
|
||||
|
||||
懒更新
|
||||
|
||||
俄罗斯方块
|
|
@ -0,0 +1,15 @@
|
|||
通过数据范围猜算法.
|
||||
IndexTree
|
||||
特点
|
||||
1) 支持区间查询
|
||||
2) 没有线段树那么强,但是非常容易改成一维,二维,三维的结构
|
||||
3) 只支持单点更新
|
||||
下标从1开始,
|
||||
下标托管,二进制,最后一位1变为0并加1,管理到自身.
|
||||
|
||||
AC自动机
|
||||
前缀数
|
||||
1) 头节点fail指针指空
|
||||
2) 头结点的子节点指头
|
||||
3) 某一个节点x,父节点通过&指向自己,父节点的file指针指向甲,甲有直接指向x的指针,则直接指过去,否则看甲的file指针,
|
||||
如果一直没有找到则指向头节点
|
|
@ -0,0 +1,3 @@
|
|||
一致性hash
|
||||
虚拟节点
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
1) 布隆过滤器用于集合的建立与查询,并可以节省大量空间
|
||||
2) 一致性哈希解决数据服务器负载管理问题
|
||||
3) 利用并查集结构做岛问题的并行计算
|
||||
4) 哈希函数可以把数据按照种类均匀分流(相同的数据一定在一块)
|
||||
5) 位图解决某一范围上数字的出现情况,并可以节省大量空间
|
||||
6) 利用分段统计思想,并进一步节省大量空间
|
||||
7) 利用堆,外排序来做多个处理单元的结果合并
|
||||
|
||||
## 4
|
||||
100G的数字文件取出出现次数最多的前100个数字.
|
||||
|
||||
将100G利用Hash分为100个文件,将每个文件里的数据统计(相同的数据必定进入同一个文件),
|
||||
取出每个文件的第一个数据,统计拿出第一个,这个就是想要的第一个数字,第一数字从那个文件中拿出,
|
||||
去原来文件拿第二个统计,取出第一个,一簇循环取出100个
|
|
@ -0,0 +1,3 @@
|
|||
数据库索引,有序表.
|
||||
AVL树:左树高度和右树高度差小于2
|
||||
默认无相同的值
|
|
@ -0,0 +1,5 @@
|
|||
## size-balance
|
||||
TreeMap
|
||||
TreeSet
|
||||
## 跳表
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
题目一
|
||||
给定一个数组arr,和两个整数a和b(a<=b),求arr中有多少个子数组,累加和在[a,b]这个范围上,返回达标
|
||||
的子数组数量.
|
|
@ -0,0 +1,8 @@
|
|||
https://shimo.im/docs/68cd6h3TwygPwx8W/read
|
||||
1) 某个面试题如果输入简单,并且只有一个实际参数
|
||||
2) 要求的返回值类型也简单,并且只有一个
|
||||
3) 用暴力方法,把输入参数对应的返回值,打印出来看看,进而优化code
|
||||
## 根据数据规模猜解法
|
||||
1) C/C++,一秒处理的指令数为10的8次方
|
||||
2) Java等语言,1~4秒处理的指令条数为10的8次方
|
||||
3) 这就是有大量的空间了.
|
|
@ -0,0 +1,54 @@
|
|||
1. 单链表、双向链表
|
||||
2. 栈队列
|
||||
## 数组做队列
|
||||
1. 数组固定长度,两个指针追赶。只用一个元素时不好实现。
|
||||
2. 添加变量队列元素个数。begin和end解耦。
|
||||
## 栈随时获取最小值
|
||||
1. 数据栈
|
||||
2. 最小栈(弹出后依然能获取最小值)
|
||||
3. 压栈,数据栈正常压入,最小栈如果压入数小于栈顶则亚如当前数,如果大于则重复压入栈顶。
|
||||
4. 弹出同步弹出。
|
||||
|
||||
## 图优先遍历
|
||||
深度优先遍历:栈
|
||||
宽度优先遍历:队列
|
||||
## 栈实现队列
|
||||
1. 设置push栈和pop栈,两个来回倒,push压入,弹出时push中的数据放入pop中,从pop中弹出。(一次性倒完,)
|
||||
## 队列实现栈
|
||||
1. 压栈放入一个队列中,需要弹栈的时候将全部放入另一个队列中,留下最后一个弹出。
|
||||
2. 再次放入,再放在当前队列中存入,弹出的时候,再次导入另一个队列中,最后一个弹出。
|
||||
## 递归
|
||||
### 递归改非递归
|
||||
使用系统栈。树遍历。
|
||||
递归到动态规划。
|
||||
大化小,递归图。
|
||||
## Master公式分析递归时间复杂度
|
||||
子问题规模一致
|
||||
## 哈希表 HashMap
|
||||
## 有序表 TreeMap
|
||||
## 归并排序
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1 @@
|
|||
A可以完全映射到B,B可以完全映射到A,一一映射 ,则AB相同
|
|
@ -0,0 +1,28 @@
|
|||
窗口问题一般都存在单调性.
|
||||
|
||||
利用单调性优化
|
||||
利用预处理结构优化+讨论来头或结尾.
|
||||
假设答案法+淘汰可能性.
|
||||
|
||||
题目四
|
||||
给定一个数组arr,给定一个值v,求子数组平均值小于等于v的最长子数组长度.
|
||||
原数组每个值减去10,累加和中小于等于0的最长子数组长度.
|
||||
|
||||
|
||||
题目五
|
||||
给定一个正方形矩阵matrix,原地调整(绕中心位置转动)成顺时针90度转动的样子
|
||||
a b c g d a
|
||||
d e f h e b
|
||||
g h i i f c
|
||||
|
||||
从外往里,一圈一圈执行.
|
||||
|
||||
圈结构
|
||||
|
||||
https://www.amysecure.com/clientarea.php
|
||||
|
||||
byware.io
|
||||
clash
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
四边形不等式技巧特征
|
||||
1. 两个可变参数的区间划分问题
|
||||
2. 每个格子有枚举行为
|
||||
3. 当两个可变参数固定一个,另一个参数和答案之间存在单调性关系
|
||||
4. 而且往往是反向单调关系
|
||||
5. 枚举加速的位置对:上➕右,或者,左➕下
|
||||
6. 不要证明!用对数器验证!
|
||||
7. 可以把时间复杂度降低一阶
|
|
@ -0,0 +1,17 @@
|
|||
## 邮局问题:
|
||||
## 扔棋子问题
|
||||
不能用二分,必须完成任务.
|
||||
f(n,k)
|
||||
n还剩多少层楼要测试,k还剩多少棋子.
|
||||
|
||||
# 四边形不等式技巧特征
|
||||
1. 两个可变参数的区间划分问题
|
||||
2. 每个格子有枚举行为
|
||||
3. 当两个可变参数固定一个,另一个参数和答案之间存在单调性关系(两个参数和结果关系)
|
||||
4. 而且往往是反向单调关系
|
||||
5. 能否获得枚举指导的位置对:上➕右,或者左➕下
|
||||
# 四边形不等式技巧注意点
|
||||
1. 不要证明用对数器验证
|
||||
2. 枚举的时候面对最优答案相等的时候怎么处理?都试试
|
||||
3. 可以把时间复杂度降低一阶
|
||||
4. 四边形不等式有些时候是最优解,有些时候不是,不是的原因:尝试思路,在根儿上不够好
|
|
@ -0,0 +1,2 @@
|
|||
## 题目三
|
||||
你有无限的1*2的砖块,要铺满M*N的区域,不同的铺法有多少种
|
|
@ -0,0 +1 @@
|
|||
分三类,S12类排序,
|
|
@ -0,0 +1,3 @@
|
|||
## 题目一
|
||||
给定两个字符串str1和str2,想把str2整体插入到str1的某个位置,形成最大的字典序,返回字典序最大的结果.
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
## 递归排序
|
||||
1. 归并分两边排序
|
||||
2. 合并,左右比较放入一个新的数据做那个
|
||||
## 归并
|
||||
1. 步长从1开始增加到数组长度。
|
||||
2. merge sort 把需要比较的数据变成有序的信息。
|
|
@ -0,0 +1 @@
|
|||
52:28
|
|
@ -0,0 +1,2 @@
|
|||
重复线段问题.
|
||||
1. 取.5判断多少线段包含.
|
|
@ -0,0 +1,3 @@
|
|||
前缀数:记录字符串出现频率.pass,end
|
||||
桶排序
|
||||
基数排序,按照个十百钱位 排序
|
After Width: | Height: | Size: 768 KiB |
After Width: | Height: | Size: 379 KiB |
After Width: | Height: | Size: 306 KiB |
After Width: | Height: | Size: 322 KiB |
After Width: | Height: | Size: 506 KiB |
After Width: | Height: | Size: 441 KiB |
After Width: | Height: | Size: 403 KiB |
After Width: | Height: | Size: 428 KiB |
After Width: | Height: | Size: 569 KiB |