This commit is contained in:
1708-huayu 2024-09-22 12:12:21 +08:00
parent 34b62d02ef
commit ed39479088
168 changed files with 4156 additions and 0 deletions

33
算法/learn/.gitignore vendored Normal file
View File

@ -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/

Binary file not shown.

View File

@ -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

316
算法/learn/mvnw vendored Normal file
View File

@ -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 "$@"

188
算法/learn/mvnw.cmd vendored Normal file
View File

@ -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%

41
算法/learn/pom.xml Normal file
View File

@ -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>

View File

@ -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];
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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];
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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];
}
}

View File

@ -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]);
}
}

View File

@ -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;
}
}

View File

@ -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最小的质数因子原因不明也不重要
// 反正打表法猜出来了
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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]);
}
}

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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];
}
}

View File

@ -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];
}
}

View File

@ -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];
}
}

View File

@ -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();
}
}

View File

@ -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;
}
}

View File

@ -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];
}
}

View File

@ -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];
}
}

View File

@ -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;
}
}

View File

@ -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];
}
}

View File

@ -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]);
}
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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");
}
}

View File

@ -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];
}
}

View File

@ -0,0 +1 @@

View File

@ -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() {
}
}

View File

@ -0,0 +1,8 @@
快慢指针.
回文
面试
1. 链表遍历与弹栈.
笔试
2. 修改右边指针往回指,分别从左右 开始遍历查看是否相同.

View File

@ -0,0 +1,8 @@
单链表环问题.
## 二叉树
### 先序
头左右
### 中序
左头右
### 后续
左右头

View File

@ -0,0 +1,9 @@
## 用队列栈实现宽度优先遍历
1. 队列弹出一个car并打印
2. car有左入左,有右入右.
## 用栈实现深度优先遍历.
1. 栈中弹出一个car并打印.
2. 有右入右,有做入左.

View File

@ -0,0 +1,14 @@
从一个节点开始,叶子节点都要,称作子树,否则称作拓扑.
### 二叉树递归套路
1. 假设以x节点为头,假设可以向x左树和x右树要任何信息
2. 在上一步的假设下,讨论以x为头节点的数,得到答案的可能性
3. 列出所有可能性后,确定到底需要向左树和右树要什么样的信息
4. 把左树信息和右树信息求全集,就是任何一颗子树都需要返回的信息S
5. 递归函数返回S,每一颗子树都这么要求
6. 写代码,在代码中考虑如何把左树信息和右树信息整合出整课数的信息
1. 思想边界提醒
2. 代码模板化

View File

@ -0,0 +1,2 @@
理清楚问题,在做..declare问题.

View File

@ -0,0 +1,5 @@
并查集:两个是否是同一个,两个联合。
往上到不能再往上,找父类.
并查集扫雷,感染并查集。
先写整体逻辑后分开写各各子实现。

View File

View File

@ -0,0 +1,7 @@
### 暴力递归
1. 把问题转换为规模缩小了的同类问题的子问题.
2. 有明确的不需要继续进行递归的条件
3. 有当得到了子问题的结果之后的决策过程
4. 不记录每一个子问题的解.
恢复现场

View File

@ -0,0 +1,9 @@
记忆化搜索
尝试策略,状态转移
自然智慧
### 问题1
给定一个整型数组arr代表数值不同的纸牌排成一条线玩家A和玩家B依次拿走每张纸牌规定玩家A先拿玩家B后拿但是每个玩家每次只能拿走最左边或者最右边的纸牌玩家A和玩家B都绝顶聪明请返回最后获胜者的分数。[50,100,20,10]

View File

@ -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
### 对数器
### 局部最小值
数据状况和问题本身梳理问题。
二分排他性
俩边开始找,根据趋势,二分处理。

View File

@ -0,0 +1,27 @@
### 背包问题
重量数组w[]
价值数据v[]
bag maxvalue int
自由挑选货物,让背包里装的货物最多
### 数字对应
规定1对应A2对应B3对应C·····26对应Z
那么一个数字字符串比如111就可以转换为AAAKAAK
给定一个只有数字字符串组成的字符串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. 业务限制模型

View File

@ -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

View File

@ -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

View File

@ -0,0 +1,4 @@
枚举行为到依赖关系(依赖下一步),斜率优化.
arr是面值数组,其中的值都是正数且没有重复.再给定一个正数aim.每个值都认为是一种面值,
且认为张数是无限的.返回组成aim的最小货币数

View File

@ -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

View File

@ -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的最少货币数
注意:
因为是求最少货币数,所以每一张货币认为是相同或者不同都不重要了.
枚举行为用邻近位置代替.

View File

@ -0,0 +1,12 @@
一个数组,输出每个位置,左侧第一个比他小的位置,右侧第一个比他小的数.
放入从小到大的栈中,相同放到一个数据放入栈中,每次弹出是结算.
题目一 给定一个只包含正数的数组arr,arr中任何一个子数组sub,一定都可以算出(sub累加和)*(sub中的最小值)是什么,
那么所有子数组中,这个值最大是多少.
以每一个位置做最小值,计算数据
第一行为底,转直方图,转单调栈.第二行为底第一行为顶计算
题目五
给定以个二维数组matrix,其中的值不是0就是1,返回全部由1组成的子矩形数量.

View File

@ -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)

View File

@ -0,0 +1,4 @@
KMP算法全称Knuth-Morris-Pratt字符串查找算法由三位发明者的姓氏命名是可以在文本串s中快速查找模式串p的一种算法。
求解next数组匹配加速.
next数组比对往右跳.

View File

@ -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压线

View File

@ -0,0 +1,3 @@
## 异或运算
无进位相加,满足结合律和交换率

View File

@ -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)
蓄水池算法
等概率进袋子.

View File

@ -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遍历.

View File

@ -0,0 +1,8 @@
i
父i/2
左2*i
右2*i+1
懒更新
俄罗斯方块

View File

@ -0,0 +1,15 @@
通过数据范围猜算法.
IndexTree
特点
1) 支持区间查询
2) 没有线段树那么强,但是非常容易改成一维,二维,三维的结构
3) 只支持单点更新
下标从1开始,
下标托管,二进制,最后一位1变为0并加1,管理到自身.
AC自动机
前缀数
1) 头节点fail指针指空
2) 头结点的子节点指头
3) 某一个节点x,父节点通过&指向自己,父节点的file指针指向甲,甲有直接指向x的指针,则直接指过去,否则看甲的file指针,
如果一直没有找到则指向头节点

View File

@ -0,0 +1,3 @@
一致性hash
虚拟节点

View File

@ -0,0 +1,14 @@
1) 布隆过滤器用于集合的建立与查询,并可以节省大量空间
2) 一致性哈希解决数据服务器负载管理问题
3) 利用并查集结构做岛问题的并行计算
4) 哈希函数可以把数据按照种类均匀分流(相同的数据一定在一块)
5) 位图解决某一范围上数字的出现情况,并可以节省大量空间
6) 利用分段统计思想,并进一步节省大量空间
7) 利用堆,外排序来做多个处理单元的结果合并
## 4
100G的数字文件取出出现次数最多的前100个数字.
将100G利用Hash分为100个文件,将每个文件里的数据统计(相同的数据必定进入同一个文件),
取出每个文件的第一个数据,统计拿出第一个,这个就是想要的第一个数字,第一数字从那个文件中拿出,
去原来文件拿第二个统计,取出第一个,一簇循环取出100个

View File

@ -0,0 +1,3 @@
数据库索引,有序表.
AVL树:左树高度和右树高度差小于2
默认无相同的值

View File

@ -0,0 +1,5 @@
## size-balance
TreeMap
TreeSet
## 跳表

View File

@ -0,0 +1,3 @@
题目一
给定一个数组arr,和两个整数a和b(a<=b),求arr中有多少个子数组,累加和在[a,b]这个范围上,返回达标
的子数组数量.

View File

@ -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) 这就是有大量的空间了.

View File

@ -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
## 归并排序

View File

@ -0,0 +1 @@
A可以完全映射到B,B可以完全映射到A,一一映射 ,则AB相同

View File

@ -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

View File

@ -0,0 +1,8 @@
四边形不等式技巧特征
1. 两个可变参数的区间划分问题
2. 每个格子有枚举行为
3. 当两个可变参数固定一个,另一个参数和答案之间存在单调性关系
4. 而且往往是反向单调关系
5. 枚举加速的位置对:上➕右,或者,左➕下
6. 不要证明!用对数器验证!
7. 可以把时间复杂度降低一阶

View File

@ -0,0 +1,17 @@
## 邮局问题:
## 扔棋子问题
不能用二分,必须完成任务.
f(n,k)
n还剩多少层楼要测试,k还剩多少棋子.
# 四边形不等式技巧特征
1. 两个可变参数的区间划分问题
2. 每个格子有枚举行为
3. 当两个可变参数固定一个,另一个参数和答案之间存在单调性关系(两个参数和结果关系)
4. 而且往往是反向单调关系
5. 能否获得枚举指导的位置对:上➕右,或者左➕下
# 四边形不等式技巧注意点
1. 不要证明用对数器验证
2. 枚举的时候面对最优答案相等的时候怎么处理?都试试
3. 可以把时间复杂度降低一阶
4. 四边形不等式有些时候是最优解,有些时候不是,不是的原因:尝试思路,在根儿上不够好

View File

@ -0,0 +1,2 @@
## 题目三
你有无限的1*2的砖块,要铺满M*N的区域,不同的铺法有多少种

View File

@ -0,0 +1 @@
分三类,S12类排序,

View File

@ -0,0 +1,3 @@
## 题目一
给定两个字符串str1和str2,想把str2整体插入到str1的某个位置,形成最大的字典序,返回字典序最大的结果.

View File

@ -0,0 +1,6 @@
## 递归排序
1. 归并分两边排序
2. 合并,左右比较放入一个新的数据做那个
## 归并
1. 步长从1开始增加到数组长度。
2. merge sort 把需要比较的数据变成有序的信息。

View File

@ -0,0 +1 @@
5228

View File

@ -0,0 +1,2 @@
重复线段问题.
1. 取.5判断多少线段包含.

View File

@ -0,0 +1,3 @@
前缀数:记录字符串出现频率.pass,end
桶排序
基数排序,按照个十百钱位 排序

Binary file not shown.

After

Width:  |  Height:  |  Size: 768 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 379 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 306 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 322 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 506 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 441 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 403 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 428 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 569 KiB

Some files were not shown because too many files have changed in this diff Show More