diff --git a/.gitignore b/.gitignore index c9418364..cf782eb8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,26 +1,8 @@ -# Generated by Cargo -# will have compiled files and executables -/target/ - -# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries -# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html -Cargo.lock - -# These are backup files generated by rustfmt -**/*.rs.bk - -leetcode.iml .idea - - -#Added by cargo - /target - +leetcode.iml +.DS_Store #Added by cargo # #already existing elements were commented out - -#/target -#Cargo.lock diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 00000000..fb0eb65a --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,1812 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "addr2line" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "aho-corasick" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +dependencies = [ + "memchr", +] + +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi 0.1.19", + "libc", + "winapi", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "backtrace" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "base64" +version = "0.21.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "bstr" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c79ad7fb2dd38f3dabd76b09c6a5a20c038fc0213ef1e9afd30eb777f120f019" +dependencies = [ + "memchr", + "serde", +] + +[[package]] +name = "bumpalo" +version = "3.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" + +[[package]] +name = "bytes" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" + +[[package]] +name = "cc" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +dependencies = [ + "jobserver", + "libc", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "chrono" +version = "0.4.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "num-traits", + "windows-targets", +] + +[[package]] +name = "chrono-tz" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e23185c0e21df6ed832a12e2bda87c7d1def6842881fb634a8511ced741b0d76" +dependencies = [ + "chrono", + "chrono-tz-build", + "phf", +] + +[[package]] +name = "chrono-tz-build" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "433e39f13c9a060046954e0592a8d0a4bcb1040125cbf91cb8ee58964cfb350f" +dependencies = [ + "parse-zoneinfo", + "phf", + "phf_codegen", +] + +[[package]] +name = "clap" +version = "3.2.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ea181bf566f71cb9a5d17a59e1871af638180a18fb0035c92ae62b705207123" +dependencies = [ + "atty", + "bitflags 1.3.2", + "clap_lex", + "indexmap", + "strsim", + "termcolor", + "textwrap", +] + +[[package]] +name = "clap_lex" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" +dependencies = [ + "os_str_bytes", +] + +[[package]] +name = "core-foundation" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" + +[[package]] +name = "cpufeatures" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce420fe07aecd3e67c5f910618fe65e94158f6dcc0adf44e00d69ce2bdfe0fd0" +dependencies = [ + "libc", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "deunicode" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71dbf1bf89c23e9cd1baf5e654f622872655f195b36588dc9dc38f7eda30758c" +dependencies = [ + "deunicode 1.4.1", +] + +[[package]] +name = "deunicode" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a1abaf4d861455be59f64fd2b55606cb151fce304ede7165f410243ce96bde6" + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", +] + +[[package]] +name = "encoding_rs" +version = "0.8.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "errno" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3e13f66a2f95e32a39eaa81f6b95d42878ca0e1db0c7543723dfe12557e860" +dependencies = [ + "libc", + "windows-sys", +] + +[[package]] +name = "fastrand" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[package]] +name = "form_urlencoded" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "futures-channel" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff4dd66668b557604244583e3e1e1eada8c5c2e96a6d0d6653ede395b78bbacb" +dependencies = [ + "futures-core", +] + +[[package]] +name = "futures-core" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb1d22c66e66d9d72e1758f0bd7d4fd0bee04cad842ee34587d68c07e45d088c" + +[[package]] +name = "futures-sink" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e36d3378ee38c2a36ad710c5d30c2911d752cb941c00c72dbabfb786a7970817" + +[[package]] +name = "futures-task" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efd193069b0ddadc69c46389b740bbccdd97203899b48d09c5f7969591d6bae2" + +[[package]] +name = "futures-util" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a19526d624e703a3179b3d322efec918b6246ea0fa51d41124525f00f1cc8104" +dependencies = [ + "futures-core", + "futures-task", + "pin-project-lite", + "pin-utils", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "gimli" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" + +[[package]] +name = "git2" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0155506aab710a86160ddb504a480d2964d7ab5b9e62419be69e0032bc5931c" +dependencies = [ + "bitflags 1.3.2", + "libc", + "libgit2-sys", + "log", + "openssl-probe", + "openssl-sys", + "url", +] + +[[package]] +name = "globset" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "759c97c1e17c55525b57192c06a267cda0ac5210b222d6b82189a2338fa1c13d" +dependencies = [ + "aho-corasick", + "bstr", + "fnv", + "log", + "regex", +] + +[[package]] +name = "globwalk" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93e3af942408868f6934a7b85134a3230832b9977cf66125df2f9edcfce4ddcc" +dependencies = [ + "bitflags 1.3.2", + "ignore", + "walkdir", +] + +[[package]] +name = "h2" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91fc23aa11be92976ef4729127f1a74adf36d8436f7816b185d18df956790833" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + +[[package]] +name = "hermit-abi" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" + +[[package]] +name = "http" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" +dependencies = [ + "bytes", + "http", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "humansize" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6cb51c9a029ddc91b07a787f1d86b53ccfa49b0e86688c946ebe8d3555685dd7" +dependencies = [ + "libm", +] + +[[package]] +name = "hyper" +version = "0.14.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2 0.4.10", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "hyper-tls" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" +dependencies = [ + "bytes", + "hyper", + "native-tls", + "tokio", + "tokio-native-tls", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8326b86b6cff230b97d0d312a6c40a60726df3332e721f72a1b035f451663b20" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "idna" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "ignore" +version = "0.4.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbe7873dab538a9a44ad79ede1faf5f30d49f9a5c883ddbab48bce81b64b7492" +dependencies = [ + "globset", + "lazy_static", + "log", + "memchr", + "regex", + "same-file", + "thread_local", + "walkdir", + "winapi-util", +] + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown", +] + +[[package]] +name = "ipnet" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" + +[[package]] +name = "itoa" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" + +[[package]] +name = "jobserver" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c37f63953c4c63420ed5fd3d6d398c719489b9f872b9fa683262f8edd363c7d" +dependencies = [ + "libc", +] + +[[package]] +name = "js-sys" +version = "0.3.65" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54c0c35952f67de54bb584e9fd912b3023117cbafc0a77d8f3dee1fb5f572fe8" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "leetcode" +version = "0.1.0" +dependencies = [ + "clap", + "git2", + "lazy_static", + "rand", + "regex", + "reqwest", + "serde", + "serde_json", + "tera", + "tokio", + "tokio-stream", +] + +[[package]] +name = "libc" +version = "0.2.149" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" + +[[package]] +name = "libgit2-sys" +version = "0.13.5+1.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51e5ea06c26926f1002dd553fded6cfcdc9784c1f60feeb58368b4d9b07b6dba" +dependencies = [ + "cc", + "libc", + "libssh2-sys", + "libz-sys", + "openssl-sys", + "pkg-config", +] + +[[package]] +name = "libm" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" + +[[package]] +name = "libssh2-sys" +version = "0.2.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b094a36eb4b8b8c8a7b4b8ae43b2944502be3e59cd87687595cf6b0a71b3f4ca" +dependencies = [ + "cc", + "libc", + "libz-sys", + "openssl-sys", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "libz-sys" +version = "1.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d97137b25e321a73eef1418d1d5d2eda4d77e12813f8e6dead84bc52c5870a7b" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "linux-raw-sys" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da2479e8c062e40bf0066ffa0bc823de0a9368974af99c9f6df941d2c231e03f" + +[[package]] +name = "log" +version = "0.4.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" + +[[package]] +name = "memchr" +version = "2.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "miniz_oxide" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +dependencies = [ + "adler", +] + +[[package]] +name = "mio" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3dce281c5e46beae905d4de1870d8b1509a9142b62eedf18b443b011ca8343d0" +dependencies = [ + "libc", + "wasi", + "windows-sys", +] + +[[package]] +name = "native-tls" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" +dependencies = [ + "lazy_static", + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + +[[package]] +name = "num-traits" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_cpus" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +dependencies = [ + "hermit-abi 0.3.3", + "libc", +] + +[[package]] +name = "object" +version = "0.32.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" + +[[package]] +name = "openssl" +version = "0.10.59" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a257ad03cd8fb16ad4172fedf8094451e1af1c4b70097636ef2eac9a5f0cc33" +dependencies = [ + "bitflags 2.4.1", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "openssl-probe" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" + +[[package]] +name = "openssl-sys" +version = "0.9.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40a4130519a360279579c2053038317e40eff64d13fd3f004f9e1b72b8a6aaf9" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "os_str_bytes" +version = "6.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2355d85b9a3786f481747ced0e0ff2ba35213a1f9bd406ed906554d7af805a1" + +[[package]] +name = "parse-zoneinfo" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c705f256449c60da65e11ff6626e0c16a0a0b96aaa348de61376b249bc340f41" +dependencies = [ + "regex", +] + +[[package]] +name = "percent-encoding" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" + +[[package]] +name = "pest" +version = "2.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae9cee2a55a544be8b89dc6848072af97a20f2422603c10865be2a42b580fff5" +dependencies = [ + "memchr", + "thiserror", + "ucd-trie", +] + +[[package]] +name = "pest_derive" +version = "2.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81d78524685f5ef2a3b3bd1cafbc9fcabb036253d9b1463e726a91cd16e2dfc2" +dependencies = [ + "pest", + "pest_generator", +] + +[[package]] +name = "pest_generator" +version = "2.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68bd1206e71118b5356dae5ddc61c8b11e28b09ef6a31acbd15ea48a28e0c227" +dependencies = [ + "pest", + "pest_meta", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "pest_meta" +version = "2.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c747191d4ad9e4a4ab9c8798f1e82a39affe7ef9648390b7e5548d18e099de6" +dependencies = [ + "once_cell", + "pest", + "sha2", +] + +[[package]] +name = "phf" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" +dependencies = [ + "phf_shared", +] + +[[package]] +name = "phf_codegen" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8d39688d359e6b34654d328e262234662d16cc0f60ec8dcbe5e718709342a5a" +dependencies = [ + "phf_generator", + "phf_shared", +] + +[[package]] +name = "phf_generator" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0" +dependencies = [ + "phf_shared", + "rand", +] + +[[package]] +name = "phf_shared" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b" +dependencies = [ + "siphasher", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkg-config" +version = "0.3.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "proc-macro2" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "redox_syscall" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "regex" +version = "1.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" + +[[package]] +name = "reqwest" +version = "0.11.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "046cd98826c46c2ac8ddecae268eb5c2e58628688a5fc7a2643704a73faba95b" +dependencies = [ + "base64", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "hyper", + "hyper-tls", + "ipnet", + "js-sys", + "log", + "mime", + "native-tls", + "once_cell", + "percent-encoding", + "pin-project-lite", + "serde", + "serde_json", + "serde_urlencoded", + "system-configuration", + "tokio", + "tokio-native-tls", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "winreg", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + +[[package]] +name = "rustix" +version = "0.38.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b426b0506e5d50a7d8dafcf2e81471400deb602392c7dd110815afb4eaf02a3" +dependencies = [ + "bitflags 2.4.1", + "errno", + "libc", + "linux-raw-sys", + "windows-sys", +] + +[[package]] +name = "ryu" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "schannel" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "security-framework" +version = "2.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "serde" +version = "1.0.190" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91d3c334ca1ee894a2c6f6ad698fe8c435b76d504b13d436f0685d648d6d96f7" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.190" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67c5609f394e5c2bd7fc51efda478004ea80ef42fee983d5c67a65e34f32c0e3" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.108" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "siphasher" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + +[[package]] +name = "slug" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3bc762e6a4b6c6fcaade73e77f9ebc6991b676f88bb2358bddb56560f073373" +dependencies = [ + "deunicode 0.4.5", +] + +[[package]] +name = "socket2" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "socket2" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" +dependencies = [ + "libc", + "windows-sys", +] + +[[package]] +name = "sort" +version = "0.1.0" + +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "syn" +version = "2.0.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "system-configuration" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "tempfile" +version = "3.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ef1adac450ad7f4b3c28589471ade84f25f731a7a0fe30d71dfa9f60fd808e5" +dependencies = [ + "cfg-if", + "fastrand", + "redox_syscall", + "rustix", + "windows-sys", +] + +[[package]] +name = "tera" +version = "1.19.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "970dff17c11e884a4a09bc76e3a17ef71e01bb13447a11e85226e254fe6d10b8" +dependencies = [ + "chrono", + "chrono-tz", + "globwalk", + "humansize", + "lazy_static", + "percent-encoding", + "pest", + "pest_derive", + "rand", + "regex", + "serde", + "serde_json", + "slug", + "unic-segment", +] + +[[package]] +name = "termcolor" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6093bad37da69aab9d123a8091e4be0aa4a03e4d601ec641c327398315f62b64" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "textwrap" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d" + +[[package]] +name = "thiserror" +version = "1.0.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "thread_local" +version = "1.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" +dependencies = [ + "cfg-if", + "once_cell", +] + +[[package]] +name = "tinyvec" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "tokio" +version = "1.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f38200e3ef7995e5ef13baec2f432a6da0aa9ac495b2c0e8f3b7eec2c92d653" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "num_cpus", + "pin-project-lite", + "socket2 0.5.5", + "tokio-macros", + "windows-sys", +] + +[[package]] +name = "tokio-macros" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tokio-native-tls" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +dependencies = [ + "native-tls", + "tokio", +] + +[[package]] +name = "tokio-stream" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "397c988d37662c7dda6d2208364a706264bf3d6138b11d436cbac0ad38832842" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", + "tracing", +] + +[[package]] +name = "tower-service" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" + +[[package]] +name = "tracing" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +dependencies = [ + "pin-project-lite", + "tracing-core", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", +] + +[[package]] +name = "try-lock" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + +[[package]] +name = "ucd-trie" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" + +[[package]] +name = "unic-char-property" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8c57a407d9b6fa02b4795eb81c5b6652060a15a7903ea981f3d723e6c0be221" +dependencies = [ + "unic-char-range", +] + +[[package]] +name = "unic-char-range" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0398022d5f700414f6b899e10b8348231abf9173fa93144cbc1a43b9793c1fbc" + +[[package]] +name = "unic-common" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80d7ff825a6a654ee85a63e80f92f054f904f21e7d12da4e22f9834a4aaa35bc" + +[[package]] +name = "unic-segment" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4ed5d26be57f84f176157270c112ef57b86debac9cd21daaabbe56db0f88f23" +dependencies = [ + "unic-ucd-segment", +] + +[[package]] +name = "unic-ucd-segment" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2079c122a62205b421f499da10f3ee0f7697f012f55b675e002483c73ea34700" +dependencies = [ + "unic-char-property", + "unic-char-range", + "unic-ucd-version", +] + +[[package]] +name = "unic-ucd-version" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96bd2f2237fe450fcd0a1d2f5f4e91711124f7857ba2e964247776ebeeb7b0c4" +dependencies = [ + "unic-common", +] + +[[package]] +name = "unicode-bidi" +version = "0.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unicode-normalization" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "url" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "walkdir" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.88" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7daec296f25a1bae309c0cd5c29c4b260e510e6d813c286b19eaadf409d40fce" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.88" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e397f4664c0e4e428e8313a469aaa58310d302159845980fd23b0f22a847f217" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9afec9963e3d0994cac82455b2b3502b81a7f40f9a0d32181f7528d9f4b43e02" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.88" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5961017b3b08ad5f3fe39f1e79877f8ee7c23c5e5fd5eb80de95abc41f1f16b2" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.88" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5353b8dab669f5e10f5bd76df26a9360c748f054f862ff5f3f8aae0c7fb3907" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.88" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d046c5d029ba91a1ed14da14dca44b68bf2f124cfbaf741c54151fdb3e0750b" + +[[package]] +name = "web-sys" +version = "0.3.65" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5db499c5f66323272151db0e666cd34f78617522fb0c1604d31a27c50c206a85" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-core" +version = "0.51.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1f8cf84f35d2db49a46868f947758c7a1138116f7fac3bc844f43ade1292e64" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "winreg" +version = "0.50.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" +dependencies = [ + "cfg-if", + "windows-sys", +] diff --git a/Cargo.toml b/Cargo.toml index 6d7c9cf9..234b6fa5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,9 +5,26 @@ authors = ["bestgopher <84328409@qq.com>"] edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[workspace] +members = ["./sort"] [dependencies] -git2 = "0.13.15" -reqwest = { version = "0.10", features = ["blocking", "json"] } +git2 = "0.14.4" +reqwest = { version = "0.11.11", features = ["json"] } serde_json = "1.0" serde = { version = "1.0", features = ["derive"] } +clap = "3.0.0-beta.2" +tera = "1.12.1" +lazy_static = "1.4.0" +regex = "1" +rand = "0.8.4" +tokio = { version = "1.33.0", features = ["fs", "macros", "rt-multi-thread"] } +tokio-stream = { version = "0.1.14", features = ["fs"] } + + +[[bin]] +name = "leetcode" +path = "src/main.rs" + +[dev-dependencies] +tokio = { version = "1.33.0", features = ["macros", "rt"] } diff --git a/README.md b/README.md index 920fad7a..94ffc560 100644 --- a/README.md +++ b/README.md @@ -1,50 +1,833 @@ # leetcode -通过rust刷leetcode题目。 -通过刷leetcode题目学习rust。 -当前已刷:13 +| Total | Easy | Medium | Hard | +| :----: | :----: | :----: | :----: | +| 823 | 368 | 427 | 28 | ### 题目 -- 07:传递信息 - - [src](https://github.com/rustors/leetcode/blob/main/src/bin/chuan-di-xin-xi.rs) - - [leetcode](https://leetcode-cn.com/problems/chuan-di-xin-xi/) -- 09:用两个栈实现队列 - - [src](https://github.com/rustors/leetcode/blob/main/src/bin/yong-liang-ge-zhan-shi-xian-dui-lie-lcof.rs) - - [leetcode](https://leetcode-cn.com/problems/yong-liang-ge-zhan-shi-xian-dui-lie-lcof/) -- 229:求众数 II - - [src](https://github.com/rustors/leetcode/blob/main/src/bin/majority-element-ii.rs) - - [leetcode](https://leetcode-cn.com/problems/majority-element-ii/) -- 367:有效的完全平方数 - - [src](https://github.com/rustors/leetcode/blob/main/src/bin/valid-perfect-square.rs) - - [leetcode](https://leetcode-cn.com/problems/valid-perfect-square/) -- 374:猜数字大小 - - [src](https://github.com/rustors/leetcode/blob/main/src/bin/guess-number-higher-or-lower.rs) - - [leetcode](https://leetcode-cn.com/problems/guess-number-higher-or-lower/) -- 387:字符串中的第一个唯一字符 - - [src](https://github.com/rustors/leetcode/blob/main/src/bin/first-unique-character-in-a-string.rs) - - [leetcode](https://leetcode-cn.com/problems/first-unique-character-in-a-string/) -- 746:检查整数及其两倍数是否存在 - - [src](https://github.com/rustors/leetcode/blob/main/src/bin/check-if-n-and-its-double-exist.rs) - - [leetcode](https://leetcode-cn.com/problems/check-if-n-and-its-double-exist/) -- 811:子域名访问计数 - - [src](https://github.com/rustors/leetcode/blob/main/src/bin/subdomain-visit-count.rs) - - [leetcode](https://leetcode-cn.com/problems/subdomain-visit-count/) -- 965:单值二叉树 - - [src](https://github.com/rustors/leetcode/blob/main/src/bin/univalued-binary-tree.rs) - - [leetcode](https://leetcode-cn.com/problems/univalued-binary-tree/) -- 1008:前序遍历构造二叉搜索树 - - [src](https://github.com/rustors/leetcode/blob/main/src/bin/construct-binary-search-tree-from-preorder-traversal.rs) - - [leetcode](https://leetcode-cn.com/problems/construct-binary-search-tree-from-preorder-traversal/) -- 1309:解码字母到整数映射 - - [src](https://github.com/rustors/leetcode/blob/main/src/bin/decrypt-string-from-alphabet-to-integer-mapping.rs) - - [leetcode](https://leetcode-cn.com/problems/decrypt-string-from-alphabet-to-integer-mapping/) -- 1432:可获得的最大点数 - - [src](https://github.com/rustors/leetcode/blob/main/src/bin/maximum-points-you-can-obtain-from-cards.rs) - - [leetcode](https://leetcode-cn.com/problems/maximum-points-you-can-obtain-from-cards/) -- 1480:一维数组的动态和 - - [src](https://github.com/rustors/leetcode/blob/main/src/bin/maximum-points-you-can-obtain-from-cards.rs) - - [leetcode](https://leetcode-cn.com/problems/running-sum-of-1d-array/) -- 1678:设计 Goal 解析器 - - [src](https://github.com/rustors/leetcode/blob/main/src/bin/goal-parser-interpretation.rs) - - [leetcode](https://leetcode-cn.com/problems/goal-parser-interpretation/) +| 编号 | 题目 | 代码 | 题目描述 | 难度 | +| ---- | ---- | ---- | ---- | ---- | +|1 | 两数之和 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/two-sum.rs) | [leetcode](https://leetcode-cn.com/problems/two-sum/) | Easy | +|2 | 两数相加 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/add-two-numbers.rs) | [leetcode](https://leetcode-cn.com/problems/add-two-numbers/) | Medium | +|3 | 无重复字符的最长子串 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/longest-substring-without-repeating-characters.rs) | [leetcode](https://leetcode-cn.com/problems/longest-substring-without-repeating-characters/) | Medium | +|4 | 寻找两个正序数组的中位数 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/median-of-two-sorted-arrays.rs) | [leetcode](https://leetcode-cn.com/problems/median-of-two-sorted-arrays/) | Hard | +|5 | 最长回文子串 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/longest-palindromic-substring.rs) | [leetcode](https://leetcode-cn.com/problems/longest-palindromic-substring/) | Medium | +|6 | Z 字形变换 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/zigzag-conversion.rs) | [leetcode](https://leetcode-cn.com/problems/zigzag-conversion/) | Medium | +|7 | 整数反转 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/reverse-integer.rs) | [leetcode](https://leetcode-cn.com/problems/reverse-integer/) | Medium | +|8 | 字符串转换整数 (atoi) | [src](https://github.com/rustors/leetcode/blob/main/src/bin/string-to-integer-atoi.rs) | [leetcode](https://leetcode-cn.com/problems/string-to-integer-atoi/) | Medium | +|9 | 回文数 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/palindrome-number.rs) | [leetcode](https://leetcode-cn.com/problems/palindrome-number/) | Easy | +|11 | 盛最多水的容器 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/container-with-most-water.rs) | [leetcode](https://leetcode-cn.com/problems/container-with-most-water/) | Medium | +|12 | 整数转罗马数字 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/integer-to-roman.rs) | [leetcode](https://leetcode-cn.com/problems/integer-to-roman/) | Medium | +|13 | 罗马数字转整数 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/roman-to-integer.rs) | [leetcode](https://leetcode-cn.com/problems/roman-to-integer/) | Easy | +|14 | 最长公共前缀 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/longest-common-prefix.rs) | [leetcode](https://leetcode-cn.com/problems/longest-common-prefix/) | Easy | +|15 | 三数之和 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/3sum.rs) | [leetcode](https://leetcode-cn.com/problems/3sum/) | Medium | +|16 | 最接近的三数之和 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/3sum-closest.rs) | [leetcode](https://leetcode-cn.com/problems/3sum-closest/) | Medium | +|17 | 电话号码的字母组合 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/letter-combinations-of-a-phone-number.rs) | [leetcode](https://leetcode-cn.com/problems/letter-combinations-of-a-phone-number/) | Medium | +|18 | 四数之和 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/4sum.rs) | [leetcode](https://leetcode-cn.com/problems/4sum/) | Medium | +|19 | 删除链表的倒数第 N 个结点 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/remove-nth-node-from-end-of-list.rs) | [leetcode](https://leetcode-cn.com/problems/remove-nth-node-from-end-of-list/) | Medium | +|20 | 有效的括号 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/valid-parentheses.rs) | [leetcode](https://leetcode-cn.com/problems/valid-parentheses/) | Easy | +|21 | 合并两个有序链表 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/merge-two-sorted-lists.rs) | [leetcode](https://leetcode-cn.com/problems/merge-two-sorted-lists/) | Easy | +|22 | 括号生成 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/generate-parentheses.rs) | [leetcode](https://leetcode-cn.com/problems/generate-parentheses/) | Medium | +|23 | 合并K个升序链表 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/merge-k-sorted-lists.rs) | [leetcode](https://leetcode-cn.com/problems/merge-k-sorted-lists/) | Hard | +|24 | 两两交换链表中的节点 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/swap-nodes-in-pairs.rs) | [leetcode](https://leetcode-cn.com/problems/swap-nodes-in-pairs/) | Medium | +|25 | K 个一组翻转链表 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/reverse-nodes-in-k-group.rs) | [leetcode](https://leetcode-cn.com/problems/reverse-nodes-in-k-group/) | Hard | +|26 | 删除有序数组中的重复项 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/remove-duplicates-from-sorted-array.rs) | [leetcode](https://leetcode-cn.com/problems/remove-duplicates-from-sorted-array/) | Easy | +|27 | 移除元素 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/remove-element.rs) | [leetcode](https://leetcode-cn.com/problems/remove-element/) | Easy | +|28 | 实现 strStr() | [src](https://github.com/rustors/leetcode/blob/main/src/bin/implement-strstr.rs) | [leetcode](https://leetcode-cn.com/problems/implement-strstr/) | Easy | +|29 | 两数相除 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/divide-two-integers.rs) | [leetcode](https://leetcode-cn.com/problems/divide-two-integers/) | Medium | +|30 | 串联所有单词的子串 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/substring-with-concatenation-of-all-words.rs) | [leetcode](https://leetcode-cn.com/problems/substring-with-concatenation-of-all-words/) | Hard | +|31 | 下一个排列 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/next-permutation.rs) | [leetcode](https://leetcode-cn.com/problems/next-permutation/) | Medium | +|32 | 最长有效括号 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/longest-valid-parentheses.rs) | [leetcode](https://leetcode-cn.com/problems/longest-valid-parentheses/) | Hard | +|33 | 搜索旋转排序数组 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/search-in-rotated-sorted-array.rs) | [leetcode](https://leetcode-cn.com/problems/search-in-rotated-sorted-array/) | Medium | +|34 | 在排序数组中查找元素的第一个和最后一个位置 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/find-first-and-last-position-of-element-in-sorted-array.rs) | [leetcode](https://leetcode-cn.com/problems/find-first-and-last-position-of-element-in-sorted-array/) | Medium | +|35 | 搜索插入位置 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/search-insert-position.rs) | [leetcode](https://leetcode-cn.com/problems/search-insert-position/) | Easy | +|36 | 有效的数独 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/valid-sudoku.rs) | [leetcode](https://leetcode-cn.com/problems/valid-sudoku/) | Medium | +|37 | 解数独 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/sudoku-solver.rs) | [leetcode](https://leetcode-cn.com/problems/sudoku-solver/) | Hard | +|37 | 解数独 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/sudoku-solver.rs) | [leetcode](https://leetcode-cn.com/problems/sudoku-solver/) | Hard | +|38 | 外观数列 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/count-and-say.rs) | [leetcode](https://leetcode-cn.com/problems/count-and-say/) | Medium | +|39 | 组合总和 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/combination-sum.rs) | [leetcode](https://leetcode-cn.com/problems/combination-sum/) | Medium | +|41 | 缺失的第一个正数 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/first-missing-positive.rs) | [leetcode](https://leetcode-cn.com/problems/first-missing-positive/) | Hard | +|42 | 接雨水 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/trapping-rain-water.rs) | [leetcode](https://leetcode-cn.com/problems/trapping-rain-water/) | Hard | +|42 | 接雨水 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/trapping-rain-water.rs) | [leetcode](https://leetcode-cn.com/problems/trapping-rain-water/) | Hard | +|43 | 字符串相乘 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/multiply-strings.rs) | [leetcode](https://leetcode-cn.com/problems/multiply-strings/) | Medium | +|45 | 跳跃游戏 II | [src](https://github.com/rustors/leetcode/blob/main/src/bin/jump-game-ii.rs) | [leetcode](https://leetcode-cn.com/problems/jump-game-ii/) | Medium | +|46 | 全排列 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/permutations.rs) | [leetcode](https://leetcode-cn.com/problems/permutations/) | Medium | +|48 | 旋转图像 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/rotate-image.rs) | [leetcode](https://leetcode-cn.com/problems/rotate-image/) | Medium | +|49 | 字母异位词分组 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/group-anagrams.rs) | [leetcode](https://leetcode-cn.com/problems/group-anagrams/) | Medium | +|50 | Pow(x, n) | [src](https://github.com/rustors/leetcode/blob/main/src/bin/powx-n.rs) | [leetcode](https://leetcode-cn.com/problems/powx-n/) | Medium | +|51 | N 皇后 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/n-queens.rs) | [leetcode](https://leetcode-cn.com/problems/n-queens/) | Hard | +|52 | N皇后 II | [src](https://github.com/rustors/leetcode/blob/main/src/bin/n-queens-ii.rs) | [leetcode](https://leetcode-cn.com/problems/n-queens-ii/) | Hard | +|53 | 最大子数组和 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/maximum-subarray.rs) | [leetcode](https://leetcode-cn.com/problems/maximum-subarray/) | Easy | +|54 | 螺旋矩阵 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/spiral-matrix.rs) | [leetcode](https://leetcode-cn.com/problems/spiral-matrix/) | Medium | +|55 | 跳跃游戏 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/jump-game.rs) | [leetcode](https://leetcode-cn.com/problems/jump-game/) | Medium | +|56 | 合并区间 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/merge-intervals.rs) | [leetcode](https://leetcode-cn.com/problems/merge-intervals/) | Medium | +|57 | 插入区间 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/insert-interval.rs) | [leetcode](https://leetcode-cn.com/problems/insert-interval/) | Medium | +|58 | 最后一个单词的长度 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/length-of-last-word.rs) | [leetcode](https://leetcode-cn.com/problems/length-of-last-word/) | Easy | +|62 | 不同路径 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/unique-paths.rs) | [leetcode](https://leetcode-cn.com/problems/unique-paths/) | Medium | +|63 | 不同路径 II | [src](https://github.com/rustors/leetcode/blob/main/src/bin/unique-paths-ii.rs) | [leetcode](https://leetcode-cn.com/problems/unique-paths-ii/) | Medium | +|64 | 最小路径和 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/minimum-path-sum.rs) | [leetcode](https://leetcode-cn.com/problems/minimum-path-sum/) | Medium | +|66 | 加一 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/plus-one.rs) | [leetcode](https://leetcode-cn.com/problems/plus-one/) | Easy | +|67 | 二进制求和 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/add-binary.rs) | [leetcode](https://leetcode-cn.com/problems/add-binary/) | Easy | +|69 | x 的平方根 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/sqrtx.rs) | [leetcode](https://leetcode-cn.com/problems/sqrtx/) | Easy | +|70 | 爬楼梯 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/climbing-stairs.rs) | [leetcode](https://leetcode-cn.com/problems/climbing-stairs/) | Easy | +|71 | 简化路径 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/simplify-path.rs) | [leetcode](https://leetcode-cn.com/problems/simplify-path/) | Medium | +|72 | 编辑距离 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/edit-distance.rs) | [leetcode](https://leetcode-cn.com/problems/edit-distance/) | Hard | +|73 | 矩阵置零 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/set-matrix-zeroes.rs) | [leetcode](https://leetcode-cn.com/problems/set-matrix-zeroes/) | Medium | +|74 | 搜索二维矩阵 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/search-a-2d-matrix.rs) | [leetcode](https://leetcode-cn.com/problems/search-a-2d-matrix/) | Medium | +|75 | 颜色分类 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/sort-colors.rs) | [leetcode](https://leetcode-cn.com/problems/sort-colors/) | Medium | +|77 | 组合 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/combinations.rs) | [leetcode](https://leetcode-cn.com/problems/combinations/) | Medium | +|78 | 子集 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/subsets.rs) | [leetcode](https://leetcode-cn.com/problems/subsets/) | Medium | +|79 | 单词搜索 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/word-search.rs) | [leetcode](https://leetcode-cn.com/problems/word-search/) | Medium | +|80 | 删除有序数组中的重复项 II | [src](https://github.com/rustors/leetcode/blob/main/src/bin/remove-duplicates-from-sorted-array-ii.rs) | [leetcode](https://leetcode-cn.com/problems/remove-duplicates-from-sorted-array-ii/) | Medium | +|81 | 搜索旋转排序数组 II | [src](https://github.com/rustors/leetcode/blob/main/src/bin/search-in-rotated-sorted-array-ii.rs) | [leetcode](https://leetcode-cn.com/problems/search-in-rotated-sorted-array-ii/) | Medium | +|82 | 删除排序链表中的重复元素 II | [src](https://github.com/rustors/leetcode/blob/main/src/bin/remove-duplicates-from-sorted-list-ii.rs) | [leetcode](https://leetcode-cn.com/problems/remove-duplicates-from-sorted-list-ii/) | Medium | +|83 | 删除排序链表中的重复元素 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/remove-duplicates-from-sorted-list.rs) | [leetcode](https://leetcode-cn.com/problems/remove-duplicates-from-sorted-list/) | Easy | +|84 | 柱状图中最大的矩形 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/largest-rectangle-in-histogram.rs) | [leetcode](https://leetcode-cn.com/problems/largest-rectangle-in-histogram/) | Hard | +|85 | 最大矩形 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/maximal-rectangle.rs) | [leetcode](https://leetcode-cn.com/problems/maximal-rectangle/) | Hard | +|86 | 分隔链表 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/partition-list.rs) | [leetcode](https://leetcode-cn.com/problems/partition-list/) | Medium | +|87 | 扰乱字符串 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/scramble-string.rs) | [leetcode](https://leetcode-cn.com/problems/scramble-string/) | Hard | +|88 | 合并两个有序数组 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/merge-sorted-array.rs) | [leetcode](https://leetcode-cn.com/problems/merge-sorted-array/) | Easy | +|89 | 格雷编码 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/gray-code.rs) | [leetcode](https://leetcode-cn.com/problems/gray-code/) | Medium | +|91 | 解码方法 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/decode-ways.rs) | [leetcode](https://leetcode-cn.com/problems/decode-ways/) | Medium | +|93 | 复原 IP 地址 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/restore-ip-addresses.rs) | [leetcode](https://leetcode-cn.com/problems/restore-ip-addresses/) | Medium | +|94 | 二叉树的中序遍历 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/binary-tree-inorder-traversal.rs) | [leetcode](https://leetcode-cn.com/problems/binary-tree-inorder-traversal/) | Easy | +|95 | 不同的二叉搜索树 II | [src](https://github.com/rustors/leetcode/blob/main/src/bin/unique-binary-search-trees-ii.rs) | [leetcode](https://leetcode-cn.com/problems/unique-binary-search-trees-ii/) | Medium | +|96 | 不同的二叉搜索树 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/unique-binary-search-trees.rs) | [leetcode](https://leetcode-cn.com/problems/unique-binary-search-trees/) | Medium | +|98 | 验证二叉搜索树 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/validate-binary-search-tree.rs) | [leetcode](https://leetcode-cn.com/problems/validate-binary-search-tree/) | Medium | +|100 | 相同的树 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/same-tree.rs) | [leetcode](https://leetcode-cn.com/problems/same-tree/) | Easy | +|101 | 对称二叉树 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/symmetric-tree.rs) | [leetcode](https://leetcode-cn.com/problems/symmetric-tree/) | Easy | +|102 | 二叉树的层序遍历 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/binary-tree-level-order-traversal.rs) | [leetcode](https://leetcode-cn.com/problems/binary-tree-level-order-traversal/) | Medium | +|103 | 二叉树的锯齿形层序遍历 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/binary-tree-zigzag-level-order-traversal.rs) | [leetcode](https://leetcode-cn.com/problems/binary-tree-zigzag-level-order-traversal/) | Medium | +|104 | 二叉树的最大深度 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/maximum-depth-of-binary-tree.rs) | [leetcode](https://leetcode-cn.com/problems/maximum-depth-of-binary-tree/) | Easy | +|105 | 从前序与中序遍历序列构造二叉树 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/construct-binary-tree-from-preorder-and-inorder-traversal.rs) | [leetcode](https://leetcode-cn.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/) | Medium | +|106 | 从中序与后序遍历序列构造二叉树 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/construct-binary-tree-from-inorder-and-postorder-traversal.rs) | [leetcode](https://leetcode-cn.com/problems/construct-binary-tree-from-inorder-and-postorder-traversal/) | Medium | +|107 | 二叉树的层序遍历 II | [src](https://github.com/rustors/leetcode/blob/main/src/bin/binary-tree-level-order-traversal-ii.rs) | [leetcode](https://leetcode-cn.com/problems/binary-tree-level-order-traversal-ii/) | Medium | +|108 | 将有序数组转换为二叉搜索树 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/convert-sorted-array-to-binary-search-tree.rs) | [leetcode](https://leetcode-cn.com/problems/convert-sorted-array-to-binary-search-tree/) | Easy | +|110 | 平衡二叉树 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/balanced-binary-tree.rs) | [leetcode](https://leetcode-cn.com/problems/balanced-binary-tree/) | Easy | +|111 | 二叉树的最小深度 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/minimum-depth-of-binary-tree.rs) | [leetcode](https://leetcode-cn.com/problems/minimum-depth-of-binary-tree/) | Easy | +|112 | 路径总和 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/path-sum.rs) | [leetcode](https://leetcode-cn.com/problems/path-sum/) | Easy | +|113 | 路径总和 II | [src](https://github.com/rustors/leetcode/blob/main/src/bin/path-sum-ii.rs) | [leetcode](https://leetcode-cn.com/problems/path-sum-ii/) | Medium | +|118 | 杨辉三角 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/pascals-triangle.rs) | [leetcode](https://leetcode-cn.com/problems/pascals-triangle/) | Easy | +|119 | 杨辉三角 II | [src](https://github.com/rustors/leetcode/blob/main/src/bin/pascals-triangle-ii.rs) | [leetcode](https://leetcode-cn.com/problems/pascals-triangle-ii/) | Easy | +|120 | 三角形最小路径和 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/triangle.rs) | [leetcode](https://leetcode-cn.com/problems/triangle/) | Medium | +|121 | 买卖股票的最佳时机 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/best-time-to-buy-and-sell-stock.rs) | [leetcode](https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock/) | Easy | +|122 | 买卖股票的最佳时机 II | [src](https://github.com/rustors/leetcode/blob/main/src/bin/best-time-to-buy-and-sell-stock-ii.rs) | [leetcode](https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-ii/) | Medium | +|124 | 二叉树中的最大路径和 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/binary-tree-maximum-path-sum.rs) | [leetcode](https://leetcode-cn.com/problems/binary-tree-maximum-path-sum/) | Hard | +|125 | 验证回文串 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/valid-palindrome.rs) | [leetcode](https://leetcode-cn.com/problems/valid-palindrome/) | Easy | +|128 | 最长连续序列 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/longest-consecutive-sequence.rs) | [leetcode](https://leetcode-cn.com/problems/longest-consecutive-sequence/) | Medium | +|129 | 求根节点到叶节点数字之和 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/sum-root-to-leaf-numbers.rs) | [leetcode](https://leetcode-cn.com/problems/sum-root-to-leaf-numbers/) | Medium | +|136 | 只出现一次的数字 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/single-number.rs) | [leetcode](https://leetcode-cn.com/problems/single-number/) | Easy | +|137 | 只出现一次的数字 II | [src](https://github.com/rustors/leetcode/blob/main/src/bin/single-number-ii.rs) | [leetcode](https://leetcode-cn.com/problems/single-number-ii/) | Medium | +|139 | 单词拆分 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/word-break.rs) | [leetcode](https://leetcode-cn.com/problems/word-break/) | Medium | +|143 | 重排链表 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/reorder-list.rs) | [leetcode](https://leetcode-cn.com/problems/reorder-list/) | Medium | +|144 | 二叉树的前序遍历 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/binary-tree-preorder-traversal.rs) | [leetcode](https://leetcode-cn.com/problems/binary-tree-preorder-traversal/) | Easy | +|145 | 二叉树的后序遍历 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/binary-tree-postorder-traversal.rs) | [leetcode](https://leetcode-cn.com/problems/binary-tree-postorder-traversal/) | Easy | +|146 | LRU 缓存 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/lru-cache.rs) | [leetcode](https://leetcode-cn.com/problems/lru-cache/) | Medium | +|148 | 排序链表 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/sort-list.rs) | [leetcode](https://leetcode-cn.com/problems/sort-list/) | Medium | +|150 | 逆波兰表达式求值 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/evaluate-reverse-polish-notation.rs) | [leetcode](https://leetcode-cn.com/problems/evaluate-reverse-polish-notation/) | Medium | +|151 | 颠倒字符串中的单词 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/reverse-words-in-a-string.rs) | [leetcode](https://leetcode-cn.com/problems/reverse-words-in-a-string/) | Medium | +|152 | 乘积最大子数组 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/maximum-product-subarray.rs) | [leetcode](https://leetcode-cn.com/problems/maximum-product-subarray/) | Medium | +|153 | 寻找旋转排序数组中的最小值 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/find-minimum-in-rotated-sorted-array.rs) | [leetcode](https://leetcode-cn.com/problems/find-minimum-in-rotated-sorted-array/) | Medium | +|154 | 寻找旋转排序数组中的最小值 II | [src](https://github.com/rustors/leetcode/blob/main/src/bin/find-minimum-in-rotated-sorted-array-ii.rs) | [leetcode](https://leetcode-cn.com/problems/find-minimum-in-rotated-sorted-array-ii/) | Hard | +|155 | 最小栈 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/min-stack.rs) | [leetcode](https://leetcode-cn.com/problems/min-stack/) | Medium | +|162 | 寻找峰值 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/find-peak-element.rs) | [leetcode](https://leetcode-cn.com/problems/find-peak-element/) | Medium | +|164 | 最大间距 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/maximum-gap.rs) | [leetcode](https://leetcode-cn.com/problems/maximum-gap/) | Medium | +|165 | 比较版本号 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/compare-version-numbers.rs) | [leetcode](https://leetcode-cn.com/problems/compare-version-numbers/) | Medium | +|166 | 分数到小数 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/fraction-to-recurring-decimal.rs) | [leetcode](https://leetcode-cn.com/problems/fraction-to-recurring-decimal/) | Medium | +|167 | 两数之和 II - 输入有序数组 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/two-sum-ii-input-array-is-sorted.rs) | [leetcode](https://leetcode-cn.com/problems/two-sum-ii-input-array-is-sorted/) | Medium | +|168 | Excel表列名称 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/excel-sheet-column-title.rs) | [leetcode](https://leetcode-cn.com/problems/excel-sheet-column-title/) | Easy | +|169 | 多数元素 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/majority-element.rs) | [leetcode](https://leetcode-cn.com/problems/majority-element/) | Easy | +|171 | Excel 表列序号 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/excel-sheet-column-number.rs) | [leetcode](https://leetcode-cn.com/problems/excel-sheet-column-number/) | Easy | +|172 | 阶乘后的零 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/factorial-trailing-zeroes.rs) | [leetcode](https://leetcode-cn.com/problems/factorial-trailing-zeroes/) | Medium | +|173 | 二叉搜索树迭代器 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/binary-search-tree-iterator.rs) | [leetcode](https://leetcode-cn.com/problems/binary-search-tree-iterator/) | Medium | +|187 | 重复的DNA序列 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/repeated-dna-sequences.rs) | [leetcode](https://leetcode-cn.com/problems/repeated-dna-sequences/) | Medium | +|190 | 颠倒二进制位 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/reverse-bits.rs) | [leetcode](https://leetcode-cn.com/problems/reverse-bits/) | Easy | +|191 | 位1的个数 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/number-of-1-bits.rs) | [leetcode](https://leetcode-cn.com/problems/number-of-1-bits/) | Easy | +|198 | 打家劫舍 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/house-robber.rs) | [leetcode](https://leetcode-cn.com/problems/house-robber/) | Medium | +|199 | 二叉树的右视图 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/binary-tree-right-side-view.rs) | [leetcode](https://leetcode-cn.com/problems/binary-tree-right-side-view/) | Medium | +|200 | 岛屿数量 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/number-of-islands.rs) | [leetcode](https://leetcode-cn.com/problems/number-of-islands/) | Medium | +|201 | 数字范围按位与 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/bitwise-and-of-numbers-range.rs) | [leetcode](https://leetcode-cn.com/problems/bitwise-and-of-numbers-range/) | Medium | +|202 | 快乐数 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/happy-number.rs) | [leetcode](https://leetcode-cn.com/problems/happy-number/) | Easy | +|203 | 移除链表元素 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/remove-linked-list-elements.rs) | [leetcode](https://leetcode-cn.com/problems/remove-linked-list-elements/) | Easy | +|204 | 计数质数 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/count-primes.rs) | [leetcode](https://leetcode-cn.com/problems/count-primes/) | Medium | +|205 | 同构字符串 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/isomorphic-strings.rs) | [leetcode](https://leetcode-cn.com/problems/isomorphic-strings/) | Easy | +|206 | 反转链表 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/reverse-linked-list.rs) | [leetcode](https://leetcode-cn.com/problems/reverse-linked-list/) | Easy | +|207 | 课程表 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/course-schedule.rs) | [leetcode](https://leetcode-cn.com/problems/course-schedule/) | Medium | +|208 | 实现 Trie (前缀树) | [src](https://github.com/rustors/leetcode/blob/main/src/bin/implement-trie-prefix-tree.rs) | [leetcode](https://leetcode-cn.com/problems/implement-trie-prefix-tree/) | Medium | +|211 | 添加与搜索单词 - 数据结构设计 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/design-add-and-search-words-data-structure.rs) | [leetcode](https://leetcode-cn.com/problems/design-add-and-search-words-data-structure/) | Medium | +|213 | 打家劫舍 II | [src](https://github.com/rustors/leetcode/blob/main/src/bin/house-robber-ii.rs) | [leetcode](https://leetcode-cn.com/problems/house-robber-ii/) | Medium | +|215 | 数组中的第K个最大元素 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/kth-largest-element-in-an-array.rs) | [leetcode](https://leetcode-cn.com/problems/kth-largest-element-in-an-array/) | Medium | +|216 | 组合总和 III | [src](https://github.com/rustors/leetcode/blob/main/src/bin/combination-sum-iii.rs) | [leetcode](https://leetcode-cn.com/problems/combination-sum-iii/) | Medium | +|217 | 存在重复元素 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/contains-duplicate.rs) | [leetcode](https://leetcode-cn.com/problems/contains-duplicate/) | Easy | +|219 | 存在重复元素 II | [src](https://github.com/rustors/leetcode/blob/main/src/bin/contains-duplicate-ii.rs) | [leetcode](https://leetcode-cn.com/problems/contains-duplicate-ii/) | Easy | +|222 | 完全二叉树的节点个数 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/count-complete-tree-nodes.rs) | [leetcode](https://leetcode-cn.com/problems/count-complete-tree-nodes/) | Medium | +|223 | 矩形面积 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/rectangle-area.rs) | [leetcode](https://leetcode-cn.com/problems/rectangle-area/) | Medium | +|225 | 用队列实现栈 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/implement-stack-using-queues.rs) | [leetcode](https://leetcode-cn.com/problems/implement-stack-using-queues/) | Easy | +|226 | 翻转二叉树 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/invert-binary-tree.rs) | [leetcode](https://leetcode-cn.com/problems/invert-binary-tree/) | Easy | +|228 | 汇总区间 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/summary-ranges.rs) | [leetcode](https://leetcode-cn.com/problems/summary-ranges/) | Easy | +|229 | 多数元素 II | [src](https://github.com/rustors/leetcode/blob/main/src/bin/majority-element-ii.rs) | [leetcode](https://leetcode-cn.com/problems/majority-element-ii/) | Medium | +|230 | 二叉搜索树中第K小的元素 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/kth-smallest-element-in-a-bst.rs) | [leetcode](https://leetcode-cn.com/problems/kth-smallest-element-in-a-bst/) | Medium | +|231 | 2 的幂 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/power-of-two.rs) | [leetcode](https://leetcode-cn.com/problems/power-of-two/) | Easy | +|232 | 用栈实现队列 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/implement-queue-using-stacks.rs) | [leetcode](https://leetcode-cn.com/problems/implement-queue-using-stacks/) | Easy | +|234 | 回文链表 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/palindrome-linked-list.rs) | [leetcode](https://leetcode-cn.com/problems/palindrome-linked-list/) | Easy | +|235 | 二叉搜索树的最近公共祖先 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/lowest-common-ancestor-of-a-binary-search-tree.rs) | [leetcode](https://leetcode-cn.com/problems/lowest-common-ancestor-of-a-binary-search-tree/) | Easy | +|236 | 二叉树的最近公共祖先 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/lowest-common-ancestor-of-a-binary-tree.rs) | [leetcode](https://leetcode-cn.com/problems/lowest-common-ancestor-of-a-binary-tree/) | Medium | +|238 | 除自身以外数组的乘积 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/product-of-array-except-self.rs) | [leetcode](https://leetcode-cn.com/problems/product-of-array-except-self/) | Medium | +|239 | 滑动窗口最大值 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/sliding-window-maximum.rs) | [leetcode](https://leetcode-cn.com/problems/sliding-window-maximum/) | Hard | +|240 | 搜索二维矩阵 II | [src](https://github.com/rustors/leetcode/blob/main/src/bin/search-a-2d-matrix-ii.rs) | [leetcode](https://leetcode-cn.com/problems/search-a-2d-matrix-ii/) | Medium | +|242 | 有效的字母异位词 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/valid-anagram.rs) | [leetcode](https://leetcode-cn.com/problems/valid-anagram/) | Easy | +|257 | 二叉树的所有路径 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/binary-tree-paths.rs) | [leetcode](https://leetcode-cn.com/problems/binary-tree-paths/) | Easy | +|258 | 各位相加 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/add-digits.rs) | [leetcode](https://leetcode-cn.com/problems/add-digits/) | Easy | +|260 | 只出现一次的数字 III | [src](https://github.com/rustors/leetcode/blob/main/src/bin/single-number-iii.rs) | [leetcode](https://leetcode-cn.com/problems/single-number-iii/) | Medium | +|263 | 丑数 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/ugly-number.rs) | [leetcode](https://leetcode-cn.com/problems/ugly-number/) | Easy | +|268 | 丢失的数字 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/missing-number.rs) | [leetcode](https://leetcode-cn.com/problems/missing-number/) | Easy | +|274 | H 指数 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/h-index.rs) | [leetcode](https://leetcode-cn.com/problems/h-index/) | Medium | +|275 | H 指数 II | [src](https://github.com/rustors/leetcode/blob/main/src/bin/h-index-ii.rs) | [leetcode](https://leetcode-cn.com/problems/h-index-ii/) | Medium | +|278 | 第一个错误的版本 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/first-bad-version.rs) | [leetcode](https://leetcode-cn.com/problems/first-bad-version/) | Easy | +|279 | 完全平方数 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/perfect-squares.rs) | [leetcode](https://leetcode-cn.com/problems/perfect-squares/) | Medium | +|283 | 移动零 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/move-zeroes.rs) | [leetcode](https://leetcode-cn.com/problems/move-zeroes/) | Easy | +|287 | 寻找重复数 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/find-the-duplicate-number.rs) | [leetcode](https://leetcode-cn.com/problems/find-the-duplicate-number/) | Medium | +|290 | 单词规律 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/word-pattern.rs) | [leetcode](https://leetcode-cn.com/problems/word-pattern/) | Easy | +|292 | Nim 游戏 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/nim-game.rs) | [leetcode](https://leetcode-cn.com/problems/nim-game/) | Easy | +|297 | 二叉树的序列化与反序列化 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/serialize-and-deserialize-binary-tree.rs) | [leetcode](https://leetcode-cn.com/problems/serialize-and-deserialize-binary-tree/) | Hard | +|299 | 猜数字游戏 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/bulls-and-cows.rs) | [leetcode](https://leetcode-cn.com/problems/bulls-and-cows/) | Medium | +|300 | 最长递增子序列 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/longest-increasing-subsequence.rs) | [leetcode](https://leetcode-cn.com/problems/longest-increasing-subsequence/) | Medium | +|303 | 区域和检索 - 数组不可变 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/range-sum-query-immutable.rs) | [leetcode](https://leetcode-cn.com/problems/range-sum-query-immutable/) | Easy | +|307 | 区域和检索 - 数组可修改 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/range-sum-query-mutable.rs) | [leetcode](https://leetcode-cn.com/problems/range-sum-query-mutable/) | Medium | +|309 | 最佳买卖股票时机含冷冻期 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/best-time-to-buy-and-sell-stock-with-cooldown.rs) | [leetcode](https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-with-cooldown/) | Medium | +|318 | 最大单词长度乘积 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/maximum-product-of-word-lengths.rs) | [leetcode](https://leetcode-cn.com/problems/maximum-product-of-word-lengths/) | Medium | +|319 | 灯泡开关 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/bulb-switcher.rs) | [leetcode](https://leetcode-cn.com/problems/bulb-switcher/) | Medium | +|322 | 零钱兑换 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/coin-change.rs) | [leetcode](https://leetcode-cn.com/problems/coin-change/) | Medium | +|326 | 3 的幂 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/power-of-three.rs) | [leetcode](https://leetcode-cn.com/problems/power-of-three/) | Easy | +|331 | 验证二叉树的前序序列化 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/verify-preorder-serialization-of-a-binary-tree.rs) | [leetcode](https://leetcode-cn.com/problems/verify-preorder-serialization-of-a-binary-tree/) | Medium | +|334 | 递增的三元子序列 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/increasing-triplet-subsequence.rs) | [leetcode](https://leetcode-cn.com/problems/increasing-triplet-subsequence/) | Medium | +|337 | 打家劫舍 III | [src](https://github.com/rustors/leetcode/blob/main/src/bin/house-robber-iii.rs) | [leetcode](https://leetcode-cn.com/problems/house-robber-iii/) | Medium | +|338 | 比特位计数 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/counting-bits.rs) | [leetcode](https://leetcode-cn.com/problems/counting-bits/) | Easy | +|344 | 反转字符串 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/reverse-string.rs) | [leetcode](https://leetcode-cn.com/problems/reverse-string/) | Easy | +|345 | 反转字符串中的元音字母 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/reverse-vowels-of-a-string.rs) | [leetcode](https://leetcode-cn.com/problems/reverse-vowels-of-a-string/) | Easy | +|347 | 前 K 个高频元素 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/top-k-frequent-elements.rs) | [leetcode](https://leetcode-cn.com/problems/top-k-frequent-elements/) | Medium | +|349 | 两个数组的交集 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/intersection-of-two-arrays.rs) | [leetcode](https://leetcode-cn.com/problems/intersection-of-two-arrays/) | Easy | +|350 | 两个数组的交集 II | [src](https://github.com/rustors/leetcode/blob/main/src/bin/intersection-of-two-arrays-ii.rs) | [leetcode](https://leetcode-cn.com/problems/intersection-of-two-arrays-ii/) | Easy | +|355 | 设计推特 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/design-twitter.rs) | [leetcode](https://leetcode-cn.com/problems/design-twitter/) | Medium | +|357 | 统计各位数字都不同的数字个数 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/count-numbers-with-unique-digits.rs) | [leetcode](https://leetcode-cn.com/problems/count-numbers-with-unique-digits/) | Medium | +|365 | 水壶问题 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/water-and-jug-problem.rs) | [leetcode](https://leetcode-cn.com/problems/water-and-jug-problem/) | Medium | +|367 | 有效的完全平方数 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/valid-perfect-square.rs) | [leetcode](https://leetcode-cn.com/problems/valid-perfect-square/) | Easy | +|371 | 两整数之和 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/sum-of-two-integers.rs) | [leetcode](https://leetcode-cn.com/problems/sum-of-two-integers/) | Medium | +|374 | 猜数字大小 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/guess-number-higher-or-lower.rs) | [leetcode](https://leetcode-cn.com/problems/guess-number-higher-or-lower/) | Easy | +|376 | 摆动序列 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/wiggle-subsequence.rs) | [leetcode](https://leetcode-cn.com/problems/wiggle-subsequence/) | Medium | +|377 | 组合总和 Ⅳ | [src](https://github.com/rustors/leetcode/blob/main/src/bin/combination-sum-iv.rs) | [leetcode](https://leetcode-cn.com/problems/combination-sum-iv/) | Medium | +|378 | 有序矩阵中第 K 小的元素 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/kth-smallest-element-in-a-sorted-matrix.rs) | [leetcode](https://leetcode-cn.com/problems/kth-smallest-element-in-a-sorted-matrix/) | Medium | +|380 | O(1) 时间插入、删除和获取随机元素 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/insert-delete-getrandom-o1.rs) | [leetcode](https://leetcode-cn.com/problems/insert-delete-getrandom-o1/) | Medium | +|381 | O(1) 时间插入、删除和获取随机元素 - 允许重复 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/insert-delete-getrandom-o1-duplicates-allowed.rs) | [leetcode](https://leetcode-cn.com/problems/insert-delete-getrandom-o1-duplicates-allowed/) | Hard | +|382 | 链表随机节点 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/linked-list-random-node.rs) | [leetcode](https://leetcode-cn.com/problems/linked-list-random-node/) | Medium | +|383 | 赎金信 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/ransom-note.rs) | [leetcode](https://leetcode-cn.com/problems/ransom-note/) | Easy | +|384 | 打乱数组 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/shuffle-an-array.rs) | [leetcode](https://leetcode-cn.com/problems/shuffle-an-array/) | Medium | +|386 | 字典序排数 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/lexicographical-numbers.rs) | [leetcode](https://leetcode-cn.com/problems/lexicographical-numbers/) | Medium | +|387 | 字符串中的第一个唯一字符 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/first-unique-character-in-a-string.rs) | [leetcode](https://leetcode-cn.com/problems/first-unique-character-in-a-string/) | Easy | +|389 | 找不同 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/find-the-difference.rs) | [leetcode](https://leetcode-cn.com/problems/find-the-difference/) | Easy | +|390 | 消除游戏 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/elimination-game.rs) | [leetcode](https://leetcode-cn.com/problems/elimination-game/) | Medium | +|392 | 判断子序列 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/is-subsequence.rs) | [leetcode](https://leetcode-cn.com/problems/is-subsequence/) | Easy | +|393 | UTF-8 编码验证 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/utf-8-validation.rs) | [leetcode](https://leetcode-cn.com/problems/utf-8-validation/) | Medium | +|397 | 整数替换 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/integer-replacement.rs) | [leetcode](https://leetcode-cn.com/problems/integer-replacement/) | Medium | +|398 | 随机数索引 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/random-pick-index.rs) | [leetcode](https://leetcode-cn.com/problems/random-pick-index/) | Medium | +|400 | 第 N 位数字 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/nth-digit.rs) | [leetcode](https://leetcode-cn.com/problems/nth-digit/) | Medium | +|401 | 二进制手表 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/binary-watch.rs) | [leetcode](https://leetcode-cn.com/problems/binary-watch/) | Easy | +|404 | 左叶子之和 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/sum-of-left-leaves.rs) | [leetcode](https://leetcode-cn.com/problems/sum-of-left-leaves/) | Easy | +|406 | 根据身高重建队列 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/queue-reconstruction-by-height.rs) | [leetcode](https://leetcode-cn.com/problems/queue-reconstruction-by-height/) | Medium | +|409 | 最长回文串 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/longest-palindrome.rs) | [leetcode](https://leetcode-cn.com/problems/longest-palindrome/) | Easy | +|412 | Fizz Buzz | [src](https://github.com/rustors/leetcode/blob/main/src/bin/fizz-buzz.rs) | [leetcode](https://leetcode-cn.com/problems/fizz-buzz/) | Easy | +|413 | 等差数列划分 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/arithmetic-slices.rs) | [leetcode](https://leetcode-cn.com/problems/arithmetic-slices/) | Medium | +|414 | 第三大的数 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/third-maximum-number.rs) | [leetcode](https://leetcode-cn.com/problems/third-maximum-number/) | Easy | +|415 | 字符串相加 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/add-strings.rs) | [leetcode](https://leetcode-cn.com/problems/add-strings/) | Easy | +|419 | 甲板上的战舰 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/battleships-in-a-board.rs) | [leetcode](https://leetcode-cn.com/problems/battleships-in-a-board/) | Medium | +|423 | 从英文中重建数字 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/reconstruct-original-digits-from-english.rs) | [leetcode](https://leetcode-cn.com/problems/reconstruct-original-digits-from-english/) | Medium | +|434 | 字符串中的单词数 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/number-of-segments-in-a-string.rs) | [leetcode](https://leetcode-cn.com/problems/number-of-segments-in-a-string/) | Easy | +|437 | 路径总和 III | [src](https://github.com/rustors/leetcode/blob/main/src/bin/path-sum-iii.rs) | [leetcode](https://leetcode-cn.com/problems/path-sum-iii/) | Medium | +|438 | 找到字符串中所有字母异位词 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/find-all-anagrams-in-a-string.rs) | [leetcode](https://leetcode-cn.com/problems/find-all-anagrams-in-a-string/) | Medium | +|442 | 数组中重复的数据 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/find-all-duplicates-in-an-array.rs) | [leetcode](https://leetcode-cn.com/problems/find-all-duplicates-in-an-array/) | Medium | +|445 | 两数相加 II | [src](https://github.com/rustors/leetcode/blob/main/src/bin/add-two-numbers-ii.rs) | [leetcode](https://leetcode-cn.com/problems/add-two-numbers-ii/) | Medium | +|447 | 回旋镖的数量 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/number-of-boomerangs.rs) | [leetcode](https://leetcode-cn.com/problems/number-of-boomerangs/) | Medium | +|448 | 找到所有数组中消失的数字 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/find-all-numbers-disappeared-in-an-array.rs) | [leetcode](https://leetcode-cn.com/problems/find-all-numbers-disappeared-in-an-array/) | Easy | +|449 | 序列化和反序列化二叉搜索树 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/serialize-and-deserialize-bst.rs) | [leetcode](https://leetcode-cn.com/problems/serialize-and-deserialize-bst/) | Medium | +|460 | LFU 缓存 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/lfu-cache.rs) | [leetcode](https://leetcode-cn.com/problems/lfu-cache/) | Hard | +|461 | 汉明距离 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/hamming-distance.rs) | [leetcode](https://leetcode-cn.com/problems/hamming-distance/) | Easy | +|476 | 数字的补数 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/number-complement.rs) | [leetcode](https://leetcode-cn.com/problems/number-complement/) | Easy | +|481 | 神奇字符串 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/magical-string.rs) | [leetcode](https://leetcode-cn.com/problems/magical-string/) | Medium | +|485 | 最大连续 1 的个数 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/max-consecutive-ones.rs) | [leetcode](https://leetcode-cn.com/problems/max-consecutive-ones/) | Easy | +|486 | 预测赢家 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/predict-the-winner.rs) | [leetcode](https://leetcode-cn.com/problems/predict-the-winner/) | Medium | +|489 | 第 K 条最小指令 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/kth-smallest-instructions.rs) | [leetcode](https://leetcode-cn.com/problems/kth-smallest-instructions/) | Hard | +|494 | 目标和 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/target-sum.rs) | [leetcode](https://leetcode-cn.com/problems/target-sum/) | Medium | +|494 | 目标和 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/target-sum.rs) | [leetcode](https://leetcode-cn.com/problems/target-sum/) | Medium | +|500 | 键盘行 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/keyboard-row.rs) | [leetcode](https://leetcode-cn.com/problems/keyboard-row/) | Easy | +|504 | 七进制数 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/base-7.rs) | [leetcode](https://leetcode-cn.com/problems/base-7/) | Easy | +|507 | 完美数 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/perfect-number.rs) | [leetcode](https://leetcode-cn.com/problems/perfect-number/) | Easy | +|508 | 出现次数最多的子树元素和 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/most-frequent-subtree-sum.rs) | [leetcode](https://leetcode-cn.com/problems/most-frequent-subtree-sum/) | Medium | +|513 | 找树左下角的值 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/find-bottom-left-tree-value.rs) | [leetcode](https://leetcode-cn.com/problems/find-bottom-left-tree-value/) | Medium | +|515 | 在每个树行中找最大值 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/find-largest-value-in-each-tree-row.rs) | [leetcode](https://leetcode-cn.com/problems/find-largest-value-in-each-tree-row/) | Medium | +|516 | 最长回文子序列 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/longest-palindromic-subsequence.rs) | [leetcode](https://leetcode-cn.com/problems/longest-palindromic-subsequence/) | Medium | +|518 | 零钱兑换 II | [src](https://github.com/rustors/leetcode/blob/main/src/bin/coin-change-ii.rs) | [leetcode](https://leetcode-cn.com/problems/coin-change-ii/) | Medium | +|520 | 检测大写字母 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/detect-capital.rs) | [leetcode](https://leetcode-cn.com/problems/detect-capital/) | Easy | +|521 | 最长特殊序列 Ⅰ | [src](https://github.com/rustors/leetcode/blob/main/src/bin/longest-uncommon-subsequence-i.rs) | [leetcode](https://leetcode-cn.com/problems/longest-uncommon-subsequence-i/) | Easy | +|528 | 交换链表中的节点 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/swapping-nodes-in-a-linked-list.rs) | [leetcode](https://leetcode-cn.com/problems/swapping-nodes-in-a-linked-list/) | Medium | +|530 | 二叉搜索树的最小绝对差 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/minimum-absolute-difference-in-bst.rs) | [leetcode](https://leetcode-cn.com/problems/minimum-absolute-difference-in-bst/) | Easy | +|535 | TinyURL 的加密与解密 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/encode-and-decode-tinyurl.rs) | [leetcode](https://leetcode-cn.com/problems/encode-and-decode-tinyurl/) | Medium | +|538 | 把二叉搜索树转换为累加树 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/convert-bst-to-greater-tree.rs) | [leetcode](https://leetcode-cn.com/problems/convert-bst-to-greater-tree/) | Medium | +|541 | 反转字符串 II | [src](https://github.com/rustors/leetcode/blob/main/src/bin/reverse-string-ii.rs) | [leetcode](https://leetcode-cn.com/problems/reverse-string-ii/) | Easy | +|543 | 二叉树的直径 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/diameter-of-binary-tree.rs) | [leetcode](https://leetcode-cn.com/problems/diameter-of-binary-tree/) | Easy | +|551 | 学生出勤记录 I | [src](https://github.com/rustors/leetcode/blob/main/src/bin/student-attendance-record-i.rs) | [leetcode](https://leetcode-cn.com/problems/student-attendance-record-i/) | Easy | +|560 | 和为 K 的子数组 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/subarray-sum-equals-k.rs) | [leetcode](https://leetcode-cn.com/problems/subarray-sum-equals-k/) | Medium | +|565 | 数组嵌套 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/array-nesting.rs) | [leetcode](https://leetcode-cn.com/problems/array-nesting/) | Medium | +|572 | 另一棵树的子树 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/subtree-of-another-tree.rs) | [leetcode](https://leetcode-cn.com/problems/subtree-of-another-tree/) | Easy | +|575 | 分糖果 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/distribute-candies.rs) | [leetcode](https://leetcode-cn.com/problems/distribute-candies/) | Easy | +|581 | 最短无序连续子数组 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/shortest-unsorted-continuous-subarray.rs) | [leetcode](https://leetcode-cn.com/problems/shortest-unsorted-continuous-subarray/) | Medium | +|594 | 最长和谐子序列 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/longest-harmonious-subsequence.rs) | [leetcode](https://leetcode-cn.com/problems/longest-harmonious-subsequence/) | Easy | +|599 | 两个列表的最小索引总和 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/minimum-index-sum-of-two-lists.rs) | [leetcode](https://leetcode-cn.com/problems/minimum-index-sum-of-two-lists/) | Easy | +|605 | 种花问题 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/can-place-flowers.rs) | [leetcode](https://leetcode-cn.com/problems/can-place-flowers/) | Easy | +|617 | 合并二叉树 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/merge-two-binary-trees.rs) | [leetcode](https://leetcode-cn.com/problems/merge-two-binary-trees/) | Easy | +|621 | 任务调度器 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/task-scheduler.rs) | [leetcode](https://leetcode-cn.com/problems/task-scheduler/) | Medium | +|623 | 在二叉树中增加一行 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/add-one-row-to-tree.rs) | [leetcode](https://leetcode-cn.com/problems/add-one-row-to-tree/) | Medium | +|628 | 三个数的最大乘积 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/maximum-product-of-three-numbers.rs) | [leetcode](https://leetcode-cn.com/problems/maximum-product-of-three-numbers/) | Easy | +|637 | 二叉树的层平均值 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/average-of-levels-in-binary-tree.rs) | [leetcode](https://leetcode-cn.com/problems/average-of-levels-in-binary-tree/) | Easy | +|643 | 子数组最大平均数 I | [src](https://github.com/rustors/leetcode/blob/main/src/bin/maximum-average-subarray-i.rs) | [leetcode](https://leetcode-cn.com/problems/maximum-average-subarray-i/) | Easy | +|647 | 回文子串 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/palindromic-substrings.rs) | [leetcode](https://leetcode-cn.com/problems/palindromic-substrings/) | Medium | +|649 | Dota2 参议院 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/dota2-senate.rs) | [leetcode](https://leetcode-cn.com/problems/dota2-senate/) | Medium | +|650 | 只有两个键的键盘 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/2-keys-keyboard.rs) | [leetcode](https://leetcode-cn.com/problems/2-keys-keyboard/) | Medium | +|653 | 两数之和 IV - 输入 BST | [src](https://github.com/rustors/leetcode/blob/main/src/bin/two-sum-iv-input-is-a-bst.rs) | [leetcode](https://leetcode-cn.com/problems/two-sum-iv-input-is-a-bst/) | Easy | +|657 | 机器人能否返回原点 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/robot-return-to-origin.rs) | [leetcode](https://leetcode-cn.com/problems/robot-return-to-origin/) | Easy | +|658 | 找到 K 个最接近的元素 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/find-k-closest-elements.rs) | [leetcode](https://leetcode-cn.com/problems/find-k-closest-elements/) | Medium | +|670 | 最大交换 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/maximum-swap.rs) | [leetcode](https://leetcode-cn.com/problems/maximum-swap/) | Medium | +|674 | 最长连续递增序列 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/longest-continuous-increasing-subsequence.rs) | [leetcode](https://leetcode-cn.com/problems/longest-continuous-increasing-subsequence/) | Easy | +|676 | 实现一个魔法字典 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/implement-magic-dictionary.rs) | [leetcode](https://leetcode-cn.com/problems/implement-magic-dictionary/) | Medium | +|682 | 棒球比赛 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/baseball-game.rs) | [leetcode](https://leetcode-cn.com/problems/baseball-game/) | Easy | +|718 | 最长重复子数组 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/maximum-length-of-repeated-subarray.rs) | [leetcode](https://leetcode-cn.com/problems/maximum-length-of-repeated-subarray/) | Medium | +|722 | 删除注释 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/remove-comments.rs) | [leetcode](https://leetcode-cn.com/problems/remove-comments/) | Medium | +|724 | 寻找数组的中心下标 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/find-pivot-index.rs) | [leetcode](https://leetcode-cn.com/problems/find-pivot-index/) | Easy | +|739 | 每日温度 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/daily-temperatures.rs) | [leetcode](https://leetcode-cn.com/problems/daily-temperatures/) | Medium | +|742 | 转换成小写字母 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/to-lower-case.rs) | [leetcode](https://leetcode-cn.com/problems/to-lower-case/) | Easy | +|747 | 使用最小花费爬楼梯 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/min-cost-climbing-stairs.rs) | [leetcode](https://leetcode-cn.com/problems/min-cost-climbing-stairs/) | Easy | +|782 | 宝石与石头 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/jewels-and-stones.rs) | [leetcode](https://leetcode-cn.com/problems/jewels-and-stones/) | Easy | +|783 | 二叉搜索树中的搜索 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/search-in-a-binary-search-tree.rs) | [leetcode](https://leetcode-cn.com/problems/search-in-a-binary-search-tree/) | Easy | +|784 | 二叉搜索树中的插入操作 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/insert-into-a-binary-search-tree.rs) | [leetcode](https://leetcode-cn.com/problems/insert-into-a-binary-search-tree/) | Medium | +|799 | 二叉搜索树节点最小距离 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/minimum-distance-between-bst-nodes.rs) | [leetcode](https://leetcode-cn.com/problems/minimum-distance-between-bst-nodes/) | Easy | +|800 | 字母大小写全排列 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/letter-case-permutation.rs) | [leetcode](https://leetcode-cn.com/problems/letter-case-permutation/) | Medium | +|816 | 设计哈希集合 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/design-hashset.rs) | [leetcode](https://leetcode-cn.com/problems/design-hashset/) | Easy | +|817 | 设计哈希映射 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/design-hashmap.rs) | [leetcode](https://leetcode-cn.com/problems/design-hashmap/) | Easy | +|825 | 保持城市天际线 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/max-increase-to-keep-city-skyline.rs) | [leetcode](https://leetcode-cn.com/problems/max-increase-to-keep-city-skyline/) | Medium | +|829 | 子域名访问计数 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/subdomain-visit-count.rs) | [leetcode](https://leetcode-cn.com/problems/subdomain-visit-count/) | Medium | +|834 | 模糊坐标 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/ambiguous-coordinates.rs) | [leetcode](https://leetcode-cn.com/problems/ambiguous-coordinates/) | Medium | +|835 | 链表组件 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/linked-list-components.rs) | [leetcode](https://leetcode-cn.com/problems/linked-list-components/) | Medium | +|839 | 单词的压缩编码 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/short-encoding-of-words.rs) | [leetcode](https://leetcode-cn.com/problems/short-encoding-of-words/) | Medium | +|842 | 翻转卡片游戏 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/card-flipping-game.rs) | [leetcode](https://leetcode-cn.com/problems/card-flipping-game/) | Medium | +|853 | 安排工作以达到最大收益 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/most-profit-assigning-work.rs) | [leetcode](https://leetcode-cn.com/problems/most-profit-assigning-work/) | Medium | +|857 | 较大分组的位置 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/positions-of-large-groups.rs) | [leetcode](https://leetcode-cn.com/problems/positions-of-large-groups/) | Easy | +|860 | 设计循环队列 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/design-circular-queue.rs) | [leetcode](https://leetcode-cn.com/problems/design-circular-queue/) | Medium | +|861 | 翻转图像 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/flipping-an-image.rs) | [leetcode](https://leetcode-cn.com/problems/flipping-an-image/) | Easy | +|862 | 字符串中的查找与替换 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/find-and-replace-in-string.rs) | [leetcode](https://leetcode-cn.com/problems/find-and-replace-in-string/) | Medium | +|868 | 推多米诺 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/push-dominoes.rs) | [leetcode](https://leetcode-cn.com/problems/push-dominoes/) | Medium | +|879 | 到最近的人的最大距离 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/maximize-distance-to-closest-person.rs) | [leetcode](https://leetcode-cn.com/problems/maximize-distance-to-closest-person/) | Medium | +|890 | 柠檬水找零 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/lemonade-change.rs) | [leetcode](https://leetcode-cn.com/problems/lemonade-change/) | Easy | +|903 | 用 Rand7() 实现 Rand10() | [src](https://github.com/rustors/leetcode/blob/main/src/bin/implement-rand10-using-rand7.rs) | [leetcode](https://leetcode-cn.com/problems/implement-rand10-using-rand7/) | Medium | +|904 | 叶子相似的树 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/leaf-similar-trees.rs) | [leetcode](https://leetcode-cn.com/problems/leaf-similar-trees/) | Easy | +|905 | 最长的斐波那契子序列的长度 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/length-of-longest-fibonacci-subsequence.rs) | [leetcode](https://leetcode-cn.com/problems/length-of-longest-fibonacci-subsequence/) | Medium | +|906 | 模拟行走机器人 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/walking-robot-simulation.rs) | [leetcode](https://leetcode-cn.com/problems/walking-robot-simulation/) | Medium | +|908 | 链表的中间结点 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/middle-of-the-linked-list.rs) | [leetcode](https://leetcode-cn.com/problems/middle-of-the-linked-list/) | Easy | +|917 | 救生艇 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/boats-to-save-people.rs) | [leetcode](https://leetcode-cn.com/problems/boats-to-save-people/) | Medium | +|921 | 螺旋矩阵 III | [src](https://github.com/rustors/leetcode/blob/main/src/bin/spiral-matrix-iii.rs) | [leetcode](https://leetcode-cn.com/problems/spiral-matrix-iii/) | Medium | +|924 | 公平的糖果交换 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/fair-candy-swap.rs) | [leetcode](https://leetcode-cn.com/problems/fair-candy-swap/) | Easy | +|925 | 根据前序和后序遍历构造二叉树 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/construct-binary-tree-from-preorder-and-postorder-traversal.rs) | [leetcode](https://leetcode-cn.com/problems/construct-binary-tree-from-preorder-and-postorder-traversal/) | Medium | +|928 | 三维形体的表面积 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/surface-area-of-3d-shapes.rs) | [leetcode](https://leetcode-cn.com/problems/surface-area-of-3d-shapes/) | Easy | +|930 | 所有可能的真二叉树 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/all-possible-full-binary-trees.rs) | [leetcode](https://leetcode-cn.com/problems/all-possible-full-binary-trees/) | Medium | +|930 | 所有可能的真二叉树 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/all-possible-full-binary-trees.rs) | [leetcode](https://leetcode-cn.com/problems/all-possible-full-binary-trees/) | Medium | +|930 | 所有可能的真二叉树 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/all-possible-full-binary-trees.rs) | [leetcode](https://leetcode-cn.com/problems/all-possible-full-binary-trees/) | Medium | +|932 | 单调数列 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/monotonic-array.rs) | [leetcode](https://leetcode-cn.com/problems/monotonic-array/) | Easy | +|936 | RLE 迭代器 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/rle-iterator.rs) | [leetcode](https://leetcode-cn.com/problems/rle-iterator/) | Medium | +|937 | 股票价格跨度 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/online-stock-span.rs) | [leetcode](https://leetcode-cn.com/problems/online-stock-span/) | Medium | +|947 | 在线选举 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/online-election.rs) | [leetcode](https://leetcode-cn.com/problems/online-election/) | Medium | +|950 | 卡牌分组 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/x-of-a-kind-in-a-deck-of-cards.rs) | [leetcode](https://leetcode-cn.com/problems/x-of-a-kind-in-a-deck-of-cards/) | Easy | +|953 | 仅仅反转字母 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/reverse-only-letters.rs) | [leetcode](https://leetcode-cn.com/problems/reverse-only-letters/) | Easy | +|954 | 环形子数组的最大和 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/maximum-sum-circular-subarray.rs) | [leetcode](https://leetcode-cn.com/problems/maximum-sum-circular-subarray/) | Medium | +|966 | 和相同的二元子数组 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/binary-subarrays-with-sum.rs) | [leetcode](https://leetcode-cn.com/problems/binary-subarrays-with-sum/) | Medium | +|967 | 下降路径最小和 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/minimum-falling-path-sum.rs) | [leetcode](https://leetcode-cn.com/problems/minimum-falling-path-sum/) | Medium | +|975 | 二叉搜索树的范围和 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/range-sum-of-bst.rs) | [leetcode](https://leetcode-cn.com/problems/range-sum-of-bst/) | Easy | +|977 | 不同的子序列 II | [src](https://github.com/rustors/leetcode/blob/main/src/bin/distinct-subsequences-ii.rs) | [leetcode](https://leetcode-cn.com/problems/distinct-subsequences-ii/) | Hard | +|979 | 增减字符串匹配 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/di-string-match.rs) | [leetcode](https://leetcode-cn.com/problems/di-string-match/) | Easy | +|981 | 删列造序 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/delete-columns-to-make-sorted.rs) | [leetcode](https://leetcode-cn.com/problems/delete-columns-to-make-sorted/) | Easy | +|982 | 使数组唯一的最小增量 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/minimum-increment-to-make-array-unique.rs) | [leetcode](https://leetcode-cn.com/problems/minimum-increment-to-make-array-unique/) | Medium | +|983 | 验证栈序列 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/validate-stack-sequences.rs) | [leetcode](https://leetcode-cn.com/problems/validate-stack-sequences/) | Medium | +|1002 | 最大宽度坡 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/maximum-width-ramp.rs) | [leetcode](https://leetcode-cn.com/problems/maximum-width-ramp/) | Medium | +|1005 | 单值二叉树 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/univalued-binary-tree.rs) | [leetcode](https://leetcode-cn.com/problems/univalued-binary-tree/) | Easy | +|1007 | 连续差相同的数字 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/numbers-with-same-consecutive-differences.rs) | [leetcode](https://leetcode-cn.com/problems/numbers-with-same-consecutive-differences/) | Medium | +|1010 | 强整数 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/powerful-integers.rs) | [leetcode](https://leetcode-cn.com/problems/powerful-integers/) | Medium | +|1019 | 有序数组的平方 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/squares-of-a-sorted-array.rs) | [leetcode](https://leetcode-cn.com/problems/squares-of-a-sorted-array/) | Easy | +|1021 | 在二叉树中分配硬币 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/distribute-coins-in-binary-tree.rs) | [leetcode](https://leetcode-cn.com/problems/distribute-coins-in-binary-tree/) | Medium | +|1035 | 二叉树的堂兄弟节点 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/cousins-in-binary-tree.rs) | [leetcode](https://leetcode-cn.com/problems/cousins-in-binary-tree/) | Easy | +|1036 | 腐烂的橘子 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/rotting-oranges.rs) | [leetcode](https://leetcode-cn.com/problems/rotting-oranges/) | Medium | +|1039 | 找到小镇的法官 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/find-the-town-judge.rs) | [leetcode](https://leetcode-cn.com/problems/find-the-town-judge/) | Easy | +|1041 | 可以被一步捕获的棋子数 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/available-captures-for-rook.rs) | [leetcode](https://leetcode-cn.com/problems/available-captures-for-rook/) | Easy | +|1045 | 检查替换后的词是否有效 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/check-if-word-is-valid-after-substitutions.rs) | [leetcode](https://leetcode-cn.com/problems/check-if-word-is-valid-after-substitutions/) | Medium | +|1046 | 最大连续1的个数 III | [src](https://github.com/rustors/leetcode/blob/main/src/bin/max-consecutive-ones-iii.rs) | [leetcode](https://leetcode-cn.com/problems/max-consecutive-ones-iii/) | Medium | +|1050 | 前序遍历构造二叉搜索树 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/construct-binary-search-tree-from-preorder-traversal.rs) | [leetcode](https://leetcode-cn.com/problems/construct-binary-search-tree-from-preorder-traversal/) | Medium | +|1054 | 十进制整数的反码 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/complement-of-base-10-integer.rs) | [leetcode](https://leetcode-cn.com/problems/complement-of-base-10-integer/) | Easy | +|1063 | 最佳观光组合 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/best-sightseeing-pair.rs) | [leetcode](https://leetcode-cn.com/problems/best-sightseeing-pair/) | Medium | +|1070 | 负二进制转换 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/convert-to-base-2.rs) | [leetcode](https://leetcode-cn.com/problems/convert-to-base-2/) | Medium | +|1072 | 链表中的下一个更大节点 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/next-greater-node-in-linked-list.rs) | [leetcode](https://leetcode-cn.com/problems/next-greater-node-in-linked-list/) | Medium | +|1079 | 从根到叶的二进制数之和 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/sum-of-root-to-leaf-binary-numbers.rs) | [leetcode](https://leetcode-cn.com/problems/sum-of-root-to-leaf-binary-numbers/) | Easy | +|1092 | 节点与其祖先之间的最大差值 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/maximum-difference-between-node-and-ancestor.rs) | [leetcode](https://leetcode-cn.com/problems/maximum-difference-between-node-and-ancestor/) | Medium | +|1114 | 从二叉搜索树到更大和树 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/binary-search-tree-to-greater-sum-tree.rs) | [leetcode](https://leetcode-cn.com/problems/binary-search-tree-to-greater-sum-tree/) | Medium | +|1119 | 困于环中的机器人 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/robot-bounded-in-circle.rs) | [leetcode](https://leetcode-cn.com/problems/robot-bounded-in-circle/) | Medium | +|1128 | 删除字符串中的所有相邻重复项 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/remove-all-adjacent-duplicates-in-string.rs) | [leetcode](https://leetcode-cn.com/problems/remove-all-adjacent-duplicates-in-string/) | Easy | +|1138 | 爱生气的书店老板 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/grumpy-bookstore-owner.rs) | [leetcode](https://leetcode-cn.com/problems/grumpy-bookstore-owner/) | Medium | +|1146 | 字符串的最大公因子 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/greatest-common-divisor-of-strings.rs) | [leetcode](https://leetcode-cn.com/problems/greatest-common-divisor-of-strings/) | Easy | +|1156 | Bigram 分词 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/occurrences-after-bigram.rs) | [leetcode](https://leetcode-cn.com/problems/occurrences-after-bigram/) | Easy | +|1157 | 根到叶路径上的不足节点 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/insufficient-nodes-in-root-to-leaf-paths.rs) | [leetcode](https://leetcode-cn.com/problems/insufficient-nodes-in-root-to-leaf-paths/) | Medium | +|1168 | 复写零 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/duplicate-zeros.rs) | [leetcode](https://leetcode-cn.com/problems/duplicate-zeros/) | Easy | +|1184 | 拼车 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/car-pooling.rs) | [leetcode](https://leetcode-cn.com/problems/car-pooling/) | Medium | +|1195 | 分糖果 II | [src](https://github.com/rustors/leetcode/blob/main/src/bin/distribute-candies-to-people.rs) | [leetcode](https://leetcode-cn.com/problems/distribute-candies-to-people/) | Easy | +|1195 | 分糖果 II | [src](https://github.com/rustors/leetcode/blob/main/src/bin/distribute-candies-to-people.rs) | [leetcode](https://leetcode-cn.com/problems/distribute-candies-to-people/) | Easy | +|1210 | 删除某些元素后的数组均值 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/mean-of-array-after-removing-some-elements.rs) | [leetcode](https://leetcode-cn.com/problems/mean-of-array-after-removing-some-elements/) | Easy | +|1218 | 最深叶节点的最近公共祖先 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/lowest-common-ancestor-of-deepest-leaves.rs) | [leetcode](https://leetcode-cn.com/problems/lowest-common-ancestor-of-deepest-leaves/) | Medium | +|1230 | 绝对值表达式的最大值 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/maximum-of-absolute-value-expression.rs) | [leetcode](https://leetcode-cn.com/problems/maximum-of-absolute-value-expression/) | Medium | +|1236 | 第 N 个泰波那契数 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/n-th-tribonacci-number.rs) | [leetcode](https://leetcode-cn.com/problems/n-th-tribonacci-number/) | Easy | +|1238 | 字母板上的路径 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/alphabet-board-path.rs) | [leetcode](https://leetcode-cn.com/problems/alphabet-board-path/) | Medium | +|1249 | 快照数组 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/snapshot-array.rs) | [leetcode](https://leetcode-cn.com/problems/snapshot-array/) | Medium | +|1253 | 将矩阵按对角线排序 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/sort-the-matrix-diagonally.rs) | [leetcode](https://leetcode-cn.com/problems/sort-the-matrix-diagonally/) | Medium | +|1260 | 一年中的第几天 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/day-of-the-year.rs) | [leetcode](https://leetcode-cn.com/problems/day-of-the-year/) | Easy | +|1263 | 掷骰子等于目标和的方法数 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/number-of-dice-rolls-with-target-sum.rs) | [leetcode](https://leetcode-cn.com/problems/number-of-dice-rolls-with-target-sum/) | Medium | +|1264 | 可以输入的最大单词数 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/maximum-number-of-words-you-can-type.rs) | [leetcode](https://leetcode-cn.com/problems/maximum-number-of-words-you-can-type/) | Easy | +|1273 | 比较字符串最小字母出现频次 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/compare-strings-by-frequency-of-the-smallest-character.rs) | [leetcode](https://leetcode-cn.com/problems/compare-strings-by-frequency-of-the-smallest-character/) | Medium | +|1287 | 公交站间的距离 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/distance-between-bus-stops.rs) | [leetcode](https://leetcode-cn.com/problems/distance-between-bus-stops/) | Easy | +|1289 | 一周中的第几天 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/day-of-the-week.rs) | [leetcode](https://leetcode-cn.com/problems/day-of-the-week/) | Easy | +|1293 | 存在连续三个奇数的数组 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/three-consecutive-odds.rs) | [leetcode](https://leetcode-cn.com/problems/three-consecutive-odds/) | Easy | +|1295 | 收集足够苹果的最小花园周长 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/minimum-garden-perimeter-to-collect-enough-apples.rs) | [leetcode](https://leetcode-cn.com/problems/minimum-garden-perimeter-to-collect-enough-apples/) | Medium | +|1297 | “气球” 的最大数量 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/maximum-number-of-balloons.rs) | [leetcode](https://leetcode-cn.com/problems/maximum-number-of-balloons/) | Easy | +|1303 | 得到目标值的最少行动次数 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/minimum-moves-to-reach-target-score.rs) | [leetcode](https://leetcode-cn.com/problems/minimum-moves-to-reach-target-score/) | Medium | +|1306 | 最小绝对差 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/minimum-absolute-difference.rs) | [leetcode](https://leetcode-cn.com/problems/minimum-absolute-difference/) | Easy | +|1310 | 给植物浇水 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/watering-plants.rs) | [leetcode](https://leetcode-cn.com/problems/watering-plants/) | Medium | +|1310 | 给植物浇水 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/watering-plants.rs) | [leetcode](https://leetcode-cn.com/problems/watering-plants/) | Medium | +|1319 | 独一无二的出现次数 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/unique-number-of-occurrences.rs) | [leetcode](https://leetcode-cn.com/problems/unique-number-of-occurrences/) | Easy | +|1320 | 删除字符串中的所有相邻重复项 II | [src](https://github.com/rustors/leetcode/blob/main/src/bin/remove-all-adjacent-duplicates-in-string-ii.rs) | [leetcode](https://leetcode-cn.com/problems/remove-all-adjacent-duplicates-in-string-ii/) | Medium | +|1329 | 玩筹码 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/minimum-cost-to-move-chips-to-the-same-position.rs) | [leetcode](https://leetcode-cn.com/problems/minimum-cost-to-move-chips-to-the-same-position/) | Easy | +|1341 | 分割平衡字符串 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/split-a-string-in-balanced-strings.rs) | [leetcode](https://leetcode-cn.com/problems/split-a-string-in-balanced-strings/) | Easy | +|1342 | 可以攻击国王的皇后 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/queens-that-can-attack-the-king.rs) | [leetcode](https://leetcode-cn.com/problems/queens-that-can-attack-the-king/) | Medium | +|1353 | 移除字母异位词后的结果数组 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/find-resultant-array-after-removing-anagrams.rs) | [leetcode](https://leetcode-cn.com/problems/find-resultant-array-after-removing-anagrams/) | Easy | +|1354 | 找出输掉零场或一场比赛的玩家 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/find-players-with-zero-or-one-losses.rs) | [leetcode](https://leetcode-cn.com/problems/find-players-with-zero-or-one-losses/) | Medium | +|1358 | 找出给定方程的正整数解 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/find-positive-integer-solution-for-a-given-equation.rs) | [leetcode](https://leetcode-cn.com/problems/find-positive-integer-solution-for-a-given-equation/) | Medium | +|1362 | 飞机座位分配概率 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/airplane-seat-assignment-probability.rs) | [leetcode](https://leetcode-cn.com/problems/airplane-seat-assignment-probability/) | Medium | +|1363 | 兼具大小写的最好英文字母 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/greatest-english-letter-in-upper-and-lower-case.rs) | [leetcode](https://leetcode-cn.com/problems/greatest-english-letter-in-upper-and-lower-case/) | Easy | +|1364 | 同积元组 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/tuple-with-same-product.rs) | [leetcode](https://leetcode-cn.com/problems/tuple-with-same-product/) | Medium | +|1369 | 交换字符使得字符串相同 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/minimum-swaps-to-make-strings-equal.rs) | [leetcode](https://leetcode-cn.com/problems/minimum-swaps-to-make-strings-equal/) | Medium | +|1370 | 统计「优美子数组」 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/count-number-of-nice-subarrays.rs) | [leetcode](https://leetcode-cn.com/problems/count-number-of-nice-subarrays/) | Medium | +|1371 | 移除无效的括号 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/minimum-remove-to-make-valid-parentheses.rs) | [leetcode](https://leetcode-cn.com/problems/minimum-remove-to-make-valid-parentheses/) | Medium | +|1378 | 奇数值单元格的数目 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/cells-with-odd-values-in-a-matrix.rs) | [leetcode](https://leetcode-cn.com/problems/cells-with-odd-values-in-a-matrix/) | Easy | +|1379 | 重构 2 行二进制矩阵 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/reconstruct-a-2-row-binary-matrix.rs) | [leetcode](https://leetcode-cn.com/problems/reconstruct-a-2-row-binary-matrix/) | Medium | +|1380 | 统计封闭岛屿的数目 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/number-of-closed-islands.rs) | [leetcode](https://leetcode-cn.com/problems/number-of-closed-islands/) | Medium | +|1387 | 在受污染的二叉树中查找元素 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/find-elements-in-a-contaminated-binary-tree.rs) | [leetcode](https://leetcode-cn.com/problems/find-elements-in-a-contaminated-binary-tree/) | Medium | +|1394 | 网格中的最小路径代价 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/minimum-path-cost-in-a-grid.rs) | [leetcode](https://leetcode-cn.com/problems/minimum-path-cost-in-a-grid/) | Medium | +|1395 | 访问所有点的最小时间 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/minimum-time-visiting-all-points.rs) | [leetcode](https://leetcode-cn.com/problems/minimum-time-visiting-all-points/) | Easy | +|1396 | 统计参与通信的服务器 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/count-servers-that-communicate.rs) | [leetcode](https://leetcode-cn.com/problems/count-servers-that-communicate/) | Medium | +|1396 | 统计参与通信的服务器 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/count-servers-that-communicate.rs) | [leetcode](https://leetcode-cn.com/problems/count-servers-that-communicate/) | Medium | +|1400 | 找出井字棋的获胜者 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/find-winner-on-a-tic-tac-toe-game.rs) | [leetcode](https://leetcode-cn.com/problems/find-winner-on-a-tic-tac-toe-game/) | Easy | +|1401 | 不浪费原料的汉堡制作方案 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/number-of-burgers-with-no-waste-of-ingredients.rs) | [leetcode](https://leetcode-cn.com/problems/number-of-burgers-with-no-waste-of-ingredients/) | Medium | +|1406 | 整数的各位积和之差 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/subtract-the-product-and-sum-of-digits-of-an-integer.rs) | [leetcode](https://leetcode-cn.com/problems/subtract-the-product-and-sum-of-digits-of-an-integer/) | Easy | +|1411 | 二进制链表转整数 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/convert-binary-number-in-a-linked-list-to-integer.rs) | [leetcode](https://leetcode-cn.com/problems/convert-binary-number-in-a-linked-list-to-integer/) | Easy | +|1426 | 和为零的 N 个不同整数 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/find-n-unique-integers-sum-up-to-zero.rs) | [leetcode](https://leetcode-cn.com/problems/find-n-unique-integers-sum-up-to-zero/) | Easy | +|1427 | 两棵二叉搜索树中的所有元素 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/all-elements-in-two-binary-search-trees.rs) | [leetcode](https://leetcode-cn.com/problems/all-elements-in-two-binary-search-trees/) | Medium | +|1428 | 跳跃游戏 III | [src](https://github.com/rustors/leetcode/blob/main/src/bin/jump-game-iii.rs) | [leetcode](https://leetcode-cn.com/problems/jump-game-iii/) | Medium | +|1434 | 解码字母到整数映射 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/decrypt-string-from-alphabet-to-integer-mapping.rs) | [leetcode](https://leetcode-cn.com/problems/decrypt-string-from-alphabet-to-integer-mapping/) | Easy | +|1441 | 或运算的最小翻转次数 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/minimum-flips-to-make-a-or-b-equal-to-c.rs) | [leetcode](https://leetcode-cn.com/problems/minimum-flips-to-make-a-or-b-equal-to-c/) | Medium | +|1450 | 删除给定值的叶子节点 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/delete-leaves-with-a-given-value.rs) | [leetcode](https://leetcode-cn.com/problems/delete-leaves-with-a-given-value/) | Medium | +|1455 | 餐厅过滤器 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/filter-restaurants-by-vegan-friendly-price-and-distance.rs) | [leetcode](https://leetcode-cn.com/problems/filter-restaurants-by-vegan-friendly-price-and-distance/) | Medium | +|1458 | 根据数字二进制下 1 的数目排序 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/sort-integers-by-the-number-of-1-bits.rs) | [leetcode](https://leetcode-cn.com/problems/sort-integers-by-the-number-of-1-bits/) | Easy | +|1468 | 检查整数及其两倍数是否存在 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/check-if-n-and-its-double-exist.rs) | [leetcode](https://leetcode-cn.com/problems/check-if-n-and-its-double-exist/) | Easy | +|1472 | 上升下降字符串 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/increasing-decreasing-string.rs) | [leetcode](https://leetcode-cn.com/problems/increasing-decreasing-string/) | Easy | +|1482 | 有多少小于当前数字的数字 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/how-many-numbers-are-smaller-than-the-current-number.rs) | [leetcode](https://leetcode-cn.com/problems/how-many-numbers-are-smaller-than-the-current-number/) | Easy | +|1484 | 二叉树中的链表 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/linked-list-in-binary-tree.rs) | [leetcode](https://leetcode-cn.com/problems/linked-list-in-binary-tree/) | Medium | +|1488 | 将整数按权重排序 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/sort-integers-by-the-power-value.rs) | [leetcode](https://leetcode-cn.com/problems/sort-integers-by-the-power-value/) | Medium | +|1490 | 生成每种字符都是奇数个的字符串 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/generate-a-string-with-characters-that-have-odd-counts.rs) | [leetcode](https://leetcode-cn.com/problems/generate-a-string-with-characters-that-have-odd-counts/) | Easy | +|1491 | 二进制字符串前缀一致的次数 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/number-of-times-binary-string-is-prefix-aligned.rs) | [leetcode](https://leetcode-cn.com/problems/number-of-times-binary-string-is-prefix-aligned/) | Medium | +|1501 | 圆和矩形是否有重叠 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/circle-and-rectangle-overlapping.rs) | [leetcode](https://leetcode-cn.com/problems/circle-and-rectangle-overlapping/) | Medium | +|1503 | 做菜顺序 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/reducing-dishes.rs) | [leetcode](https://leetcode-cn.com/problems/reducing-dishes/) | Hard | +|1505 | 按既定顺序创建目标数组 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/create-target-array-in-the-given-order.rs) | [leetcode](https://leetcode-cn.com/problems/create-target-array-in-the-given-order/) | Easy | +|1512 | 设计地铁系统 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/design-underground-system.rs) | [leetcode](https://leetcode-cn.com/problems/design-underground-system/) | Medium | +|1526 | HTML 实体解析器 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/html-entity-parser.rs) | [leetcode](https://leetcode-cn.com/problems/html-entity-parser/) | Medium | +|1537 | 分割字符串的最大得分 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/maximum-score-after-splitting-a-string.rs) | [leetcode](https://leetcode-cn.com/problems/maximum-score-after-splitting-a-string/) | Easy | +|1538 | 可获得的最大点数 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/maximum-points-you-can-obtain-from-cards.rs) | [leetcode](https://leetcode-cn.com/problems/maximum-points-you-can-obtain-from-cards/) | Medium | +|1544 | 统计二叉树中好节点的数目 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/count-good-nodes-in-binary-tree.rs) | [leetcode](https://leetcode-cn.com/problems/count-good-nodes-in-binary-tree/) | Medium | +|1552 | 用栈操作构建数组 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/build-an-array-with-stack-operations.rs) | [leetcode](https://leetcode-cn.com/problems/build-an-array-with-stack-operations/) | Easy | +|1566 | 检查单词是否为句中其他单词的前缀 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/check-if-a-word-occurs-as-a-prefix-of-any-word-in-a-sentence.rs) | [leetcode](https://leetcode-cn.com/problems/check-if-a-word-occurs-as-a-prefix-of-any-word-in-a-sentence/) | Easy | +|1567 | 定长子串中元音的最大数目 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/maximum-number-of-vowels-in-a-substring-of-given-length.rs) | [leetcode](https://leetcode-cn.com/problems/maximum-number-of-vowels-in-a-substring-of-given-length/) | Medium | +|1568 | 二叉树中的伪回文路径 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/pseudo-palindromic-paths-in-a-binary-tree.rs) | [leetcode](https://leetcode-cn.com/problems/pseudo-palindromic-paths-in-a-binary-tree/) | Medium | +|1575 | 切割后面积最大的蛋糕 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/maximum-area-of-a-piece-of-cake-after-horizontal-and-vertical-cuts.rs) | [leetcode](https://leetcode-cn.com/problems/maximum-area-of-a-piece-of-cake-after-horizontal-and-vertical-cuts/) | Medium | +|1576 | 重新规划路线 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/reorder-routes-to-make-all-paths-lead-to-the-city-zero.rs) | [leetcode](https://leetcode-cn.com/problems/reorder-routes-to-make-all-paths-lead-to-the-city-zero/) | Medium | +|1584 | 去掉最低工资和最高工资后的工资平均值 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/average-salary-excluding-the-minimum-and-maximum-salary.rs) | [leetcode](https://leetcode-cn.com/problems/average-salary-excluding-the-minimum-and-maximum-salary/) | Easy | +|1603 | 一维数组的动态和 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/running-sum-of-1d-array.rs) | [leetcode](https://leetcode-cn.com/problems/running-sum-of-1d-array/) | Easy | +|1604 | 不同整数的最少数目 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/least-number-of-unique-integers-after-k-removals.rs) | [leetcode](https://leetcode-cn.com/problems/least-number-of-unique-integers-after-k-removals/) | Medium | +|1620 | 检查数组对是否可以被 k 整除 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/check-if-array-pairs-are-divisible-by-k.rs) | [leetcode](https://leetcode-cn.com/problems/check-if-array-pairs-are-divisible-by-k/) | Medium | +|1630 | 在区间范围内统计奇数数目 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/count-odd-numbers-in-an-interval-range.rs) | [leetcode](https://leetcode-cn.com/problems/count-odd-numbers-in-an-interval-range/) | Easy | +|1635 | 好数对的数目 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/number-of-good-pairs.rs) | [leetcode](https://leetcode-cn.com/problems/number-of-good-pairs/) | Easy | +|1636 | 仅含 1 的子串数 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/number-of-substrings-with-only-1s.rs) | [leetcode](https://leetcode-cn.com/problems/number-of-substrings-with-only-1s/) | Medium | +|1642 | 换酒问题 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/water-bottles.rs) | [leetcode](https://leetcode-cn.com/problems/water-bottles/) | Easy | +|1656 | 统计好三元组 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/count-good-triplets.rs) | [leetcode](https://leetcode-cn.com/problems/count-good-triplets/) | Easy | +|1660 | 千位分隔数 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/thousand-separator.rs) | [leetcode](https://leetcode-cn.com/problems/thousand-separator/) | Easy | +|1666 | 整理字符串 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/make-the-string-great.rs) | [leetcode](https://leetcode-cn.com/problems/make-the-string-great/) | Easy | +|1677 | 矩阵对角线元素的和 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/matrix-diagonal-sum.rs) | [leetcode](https://leetcode-cn.com/problems/matrix-diagonal-sum/) | Easy | +|1689 | 重复至少 K 次且长度为 M 的模式 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/detect-pattern-of-length-m-repeated-k-or-more-times.rs) | [leetcode](https://leetcode-cn.com/problems/detect-pattern-of-length-m-repeated-k-or-more-times/) | Easy | +|1722 | 王位继承顺序 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/throne-inheritance.rs) | [leetcode](https://leetcode-cn.com/problems/throne-inheritance/) | Medium | +|1755 | 拆炸弹 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/defuse-the-bomb.rs) | [leetcode](https://leetcode-cn.com/problems/defuse-the-bomb/) | Easy | +|1764 | 最大重复子字符串 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/maximum-repeating-substring.rs) | [leetcode](https://leetcode-cn.com/problems/maximum-repeating-substring/) | Easy | +|1767 | 设计前中后队列 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/design-front-middle-back-queue.rs) | [leetcode](https://leetcode-cn.com/problems/design-front-middle-back-queue/) | Medium | +|1777 | 确定两个字符串是否接近 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/determine-if-two-strings-are-close.rs) | [leetcode](https://leetcode-cn.com/problems/determine-if-two-strings-are-close/) | Medium | +|1782 | 具有给定数值的最小字符串 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/smallest-string-with-a-given-numeric-value.rs) | [leetcode](https://leetcode-cn.com/problems/smallest-string-with-a-given-numeric-value/) | Medium | +|1788 | 石子游戏 VI | [src](https://github.com/rustors/leetcode/blob/main/src/bin/stone-game-vi.rs) | [leetcode](https://leetcode-cn.com/problems/stone-game-vi/) | Medium | +|1791 | 最富有客户的资产总量 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/richest-customer-wealth.rs) | [leetcode](https://leetcode-cn.com/problems/richest-customer-wealth/) | Easy | +|1797 | 设计 Goal 解析器 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/goal-parser-interpretation.rs) | [leetcode](https://leetcode-cn.com/problems/goal-parser-interpretation/) | Easy | +|1806 | 比赛中的配对次数 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/count-of-matches-in-tournament.rs) | [leetcode](https://leetcode-cn.com/problems/count-of-matches-in-tournament/) | Easy | +|1807 | 十-二进制数的最少数目 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/partitioning-into-minimum-number-of-deci-binary-numbers.rs) | [leetcode](https://leetcode-cn.com/problems/partitioning-into-minimum-number-of-deci-binary-numbers/) | Medium | +|1814 | 跳跃游戏 VI | [src](https://github.com/rustors/leetcode/blob/main/src/bin/jump-game-vi.rs) | [leetcode](https://leetcode-cn.com/problems/jump-game-vi/) | Medium | +|1817 | 计算力扣银行的钱 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/calculate-money-in-leetcode-bank.rs) | [leetcode](https://leetcode-cn.com/problems/calculate-money-in-leetcode-bank/) | Easy | +|1829 | 卡车上的最大单元数 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/maximum-units-on-a-truck.rs) | [leetcode](https://leetcode-cn.com/problems/maximum-units-on-a-truck/) | Easy | +|1833 | 找到最高海拔 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/find-the-highest-altitude.rs) | [leetcode](https://leetcode-cn.com/problems/find-the-highest-altitude/) | Easy | +|1844 | 盒子中小球的最大数量 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/maximum-number-of-balls-in-a-box.rs) | [leetcode](https://leetcode-cn.com/problems/maximum-number-of-balls-in-a-box/) | Easy | +|1849 | 任意子数组和的绝对值的最大值 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/maximum-absolute-sum-of-any-subarray.rs) | [leetcode](https://leetcode-cn.com/problems/maximum-absolute-sum-of-any-subarray/) | Medium | +|1858 | 替换隐藏数字得到的最晚时间 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/latest-time-by-replacing-hidden-digits.rs) | [leetcode](https://leetcode-cn.com/problems/latest-time-by-replacing-hidden-digits/) | Easy | +|1884 | 生成交替二进制字符串的最少操作数 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/minimum-changes-to-make-alternating-binary-string.rs) | [leetcode](https://leetcode-cn.com/problems/minimum-changes-to-make-alternating-binary-string/) | Easy | +|1894 | 交替合并字符串 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/merge-strings-alternately.rs) | [leetcode](https://leetcode-cn.com/problems/merge-strings-alternately/) | Easy | +|1899 | 统计匹配检索规则的物品数量 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/count-items-matching-a-rule.rs) | [leetcode](https://leetcode-cn.com/problems/count-items-matching-a-rule/) | Easy | +|1905 | 设计一个验证系统 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/design-authentication-manager.rs) | [leetcode](https://leetcode-cn.com/problems/design-authentication-manager/) | Medium | +|1927 | 最大升序子数组和 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/maximum-ascending-subarray-sum.rs) | [leetcode](https://leetcode-cn.com/problems/maximum-ascending-subarray-sum/) | Easy | +|1929 | 有界数组中指定下标处的最大值 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/maximum-value-at-a-given-index-in-a-bounded-array.rs) | [leetcode](https://leetcode-cn.com/problems/maximum-value-at-a-given-index-in-a-bounded-array/) | Medium | +|1938 | 最少操作使数组递增 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/minimum-operations-to-make-the-array-increasing.rs) | [leetcode](https://leetcode-cn.com/problems/minimum-operations-to-make-the-array-increasing/) | Easy | +|1940 | 每个查询的最大异或值 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/maximum-xor-for-each-query.rs) | [leetcode](https://leetcode-cn.com/problems/maximum-xor-for-each-query/) | Medium | +|1952 | 最少侧跳次数 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/minimum-sideway-jumps.rs) | [leetcode](https://leetcode-cn.com/problems/minimum-sideway-jumps/) | Medium | +|1960 | 判断句子是否为全字母句 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/check-if-the-sentence-is-pangram.rs) | [leetcode](https://leetcode-cn.com/problems/check-if-the-sentence-is-pangram/) | Easy | +|1965 | K 进制表示下的各位数字总和 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/sum-of-digits-in-base-k.rs) | [leetcode](https://leetcode-cn.com/problems/sum-of-digits-in-base-k/) | Easy | +|1971 | 增长的内存泄露 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/incremental-memory-leak.rs) | [leetcode](https://leetcode-cn.com/problems/incremental-memory-leak/) | Medium | +|1983 | 人口最多的年份 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/maximum-population-year.rs) | [leetcode](https://leetcode-cn.com/problems/maximum-population-year/) | Easy | +|1995 | 找出和为指定值的下标对 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/finding-pairs-with-a-certain-sum.rs) | [leetcode](https://leetcode-cn.com/problems/finding-pairs-with-a-certain-sum/) | Medium | +|2011 | 插入后的最大值 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/maximum-value-after-insertion.rs) | [leetcode](https://leetcode-cn.com/problems/maximum-value-after-insertion/) | Medium | +|2022 | 最大子序列交替和 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/maximum-alternating-subsequence-sum.rs) | [leetcode](https://leetcode-cn.com/problems/maximum-alternating-subsequence-sum/) | Medium | +|2032 | 字符串中的最大奇数 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/largest-odd-number-in-string.rs) | [leetcode](https://leetcode-cn.com/problems/largest-odd-number-in-string/) | Easy | +|2049 | 消灭怪物的最大数量 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/eliminate-maximum-number-of-monsters.rs) | [leetcode](https://leetcode-cn.com/problems/eliminate-maximum-number-of-monsters/) | Medium | +|2053 | 检查是否所有字符出现次数相同 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/check-if-all-characters-have-equal-number-of-occurrences.rs) | [leetcode](https://leetcode-cn.com/problems/check-if-all-characters-have-equal-number-of-occurrences/) | Easy | +|2084 | 你可以工作的最大周数 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/maximum-number-of-weeks-for-which-you-can-work.rs) | [leetcode](https://leetcode-cn.com/problems/maximum-number-of-weeks-for-which-you-can-work/) | Medium | +|2094 | 移除石子使总数最小 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/remove-stones-to-minimize-the-total.rs) | [leetcode](https://leetcode-cn.com/problems/remove-stones-to-minimize-the-total/) | Medium | +|2104 | 树上的操作 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/operations-on-tree.rs) | [leetcode](https://leetcode-cn.com/problems/operations-on-tree/) | Medium | +|2117 | 从双倍数组中还原原数组 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/find-original-array-from-doubled-array.rs) | [leetcode](https://leetcode-cn.com/problems/find-original-array-from-doubled-array/) | Medium | +|2128 | 反转单词前缀 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/reverse-prefix-of-word.rs) | [leetcode](https://leetcode-cn.com/problems/reverse-prefix-of-word/) | Easy | +|2155 | 找出缺失的观测数据 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/find-missing-observations.rs) | [leetcode](https://leetcode-cn.com/problems/find-missing-observations/) | Medium | +|2159 | 至少在两个数组中出现的值 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/two-out-of-three.rs) | [leetcode](https://leetcode-cn.com/problems/two-out-of-three/) | Easy | +|2161 | 股票价格波动 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/stock-price-fluctuation.rs) | [leetcode](https://leetcode-cn.com/problems/stock-price-fluctuation/) | Medium | +|2168 | 检查句子中的数字是否递增 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/check-if-numbers-are-ascending-in-a-sentence.rs) | [leetcode](https://leetcode-cn.com/problems/check-if-numbers-are-ascending-in-a-sentence/) | Easy | +|2169 | 简易银行系统 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/simple-bank-system.rs) | [leetcode](https://leetcode-cn.com/problems/simple-bank-system/) | Medium | +|2177 | 检查两个字符串是否几乎相等 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/check-whether-two-strings-are-almost-equivalent.rs) | [leetcode](https://leetcode-cn.com/problems/check-whether-two-strings-are-almost-equivalent/) | Easy | +|2182 | 找出临界点之间的最小和最大距离 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/find-the-minimum-and-maximum-number-of-nodes-between-critical-points.rs) | [leetcode](https://leetcode-cn.com/problems/find-the-minimum-and-maximum-number-of-nodes-between-critical-points/) | Medium | +|2190 | 统计出现过一次的公共字符串 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/count-common-words-with-one-occurrence.rs) | [leetcode](https://leetcode-cn.com/problems/count-common-words-with-one-occurrence/) | Easy | +|2195 | 买票需要的时间 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/time-needed-to-buy-tickets.rs) | [leetcode](https://leetcode-cn.com/problems/time-needed-to-buy-tickets/) | Easy | +|2210 | 找出数组排序后的目标下标 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/find-target-indices-after-sorting-array.rs) | [leetcode](https://leetcode-cn.com/problems/find-target-indices-after-sorting-array/) | Easy | +|2215 | 找出 3 位偶数 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/finding-3-digit-even-numbers.rs) | [leetcode](https://leetcode-cn.com/problems/finding-3-digit-even-numbers/) | Easy | +|2226 | 环和杆 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/rings-and-rods.rs) | [leetcode](https://leetcode-cn.com/problems/rings-and-rods/) | Easy | +|2228 | 给植物浇水 II | [src](https://github.com/rustors/leetcode/blob/main/src/bin/watering-plants-ii.rs) | [leetcode](https://leetcode-cn.com/problems/watering-plants-ii/) | Medium | +|2233 | 股票平滑下跌阶段的数目 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/number-of-smooth-descent-periods-of-a-stock.rs) | [leetcode](https://leetcode-cn.com/problems/number-of-smooth-descent-periods-of-a-stock/) | Medium | +|2235 | 将标题首字母大写 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/capitalize-the-title.rs) | [leetcode](https://leetcode-cn.com/problems/capitalize-the-title/) | Easy | +|2235 | 将标题首字母大写 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/capitalize-the-title.rs) | [leetcode](https://leetcode-cn.com/problems/capitalize-the-title/) | Easy | +|2243 | 检查是否所有 A 都在 B 之前 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/check-if-all-as-appears-before-all-bs.rs) | [leetcode](https://leetcode-cn.com/problems/check-if-all-as-appears-before-all-bs/) | Easy | +|2261 | 分组得分最高的所有下标 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/all-divisions-with-the-highest-score-of-a-binary-array.rs) | [leetcode](https://leetcode-cn.com/problems/all-divisions-with-the-highest-score-of-a-binary-array/) | Medium | +|2269 | 元素计数 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/count-elements-with-strictly-smaller-and-greater-elements.rs) | [leetcode](https://leetcode-cn.com/problems/count-elements-with-strictly-smaller-and-greater-elements/) | Easy | +|2279 | 拆分成最多数目的正偶数之和 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/maximum-split-of-positive-even-integers.rs) | [leetcode](https://leetcode-cn.com/problems/maximum-split-of-positive-even-integers/) | Medium | +|2285 | 设计位集 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/design-bitset.rs) | [leetcode](https://leetcode-cn.com/problems/design-bitset/) | Medium | +|2290 | 拿出最少数目的魔法豆 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/removing-minimum-number-of-magic-beans.rs) | [leetcode](https://leetcode-cn.com/problems/removing-minimum-number-of-magic-beans/) | Medium | +|2292 | 统计包含给定前缀的字符串 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/counting-words-with-a-given-prefix.rs) | [leetcode](https://leetcode-cn.com/problems/counting-words-with-a-given-prefix/) | Easy | +|2299 | 合并零之间的节点 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/merge-nodes-in-between-zeros.rs) | [leetcode](https://leetcode-cn.com/problems/merge-nodes-in-between-zeros/) | Medium | +|2300 | 构造限制重复的字符串 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/construct-string-with-repeat-limit.rs) | [leetcode](https://leetcode-cn.com/problems/construct-string-with-repeat-limit/) | Medium | +|2309 | 字符串中最多数目的子序列 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/maximize-number-of-subsequences-in-a-string.rs) | [leetcode](https://leetcode-cn.com/problems/maximize-number-of-subsequences-in-a-string/) | Medium | +|2310 | 将数组和减半的最少操作次数 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/minimum-operations-to-halve-array-sum.rs) | [leetcode](https://leetcode-cn.com/problems/minimum-operations-to-halve-array-sum/) | Medium | +|2320 | 找出数组中的所有 K 近邻下标 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/find-all-k-distant-indices-in-an-array.rs) | [leetcode](https://leetcode-cn.com/problems/find-all-k-distant-indices-in-an-array/) | Easy | +|2328 | 向表达式添加括号后的最小结果 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/minimize-result-by-adding-parentheses-to-expression.rs) | [leetcode](https://leetcode-cn.com/problems/minimize-result-by-adding-parentheses-to-expression/) | Medium | +|2332 | 统计圆内格点数目 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/count-lattice-points-inside-a-circle.rs) | [leetcode](https://leetcode-cn.com/problems/count-lattice-points-inside-a-circle/) | Medium | +|2346 | 字符串中最大的 3 位相同数字 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/largest-3-same-digit-number-in-string.rs) | [leetcode](https://leetcode-cn.com/problems/largest-3-same-digit-number-in-string/) | Easy | +|2351 | 买钢笔和铅笔的方案数 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/number-of-ways-to-buy-pens-and-pencils.rs) | [leetcode](https://leetcode-cn.com/problems/number-of-ways-to-buy-pens-and-pencils/) | Medium | +|2362 | 完成所有任务需要的最少轮数 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/minimum-rounds-to-complete-all-tasks.rs) | [leetcode](https://leetcode-cn.com/problems/minimum-rounds-to-complete-all-tasks/) | Medium | +|2373 | 价格减免 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/apply-discount-to-prices.rs) | [leetcode](https://leetcode-cn.com/problems/apply-discount-to-prices/) | Medium | +|2378 | 最多单词数的发件人 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/sender-with-largest-word-count.rs) | [leetcode](https://leetcode-cn.com/problems/sender-with-largest-word-count/) | Medium | +|2384 | 判断根结点是否等于子结点之和 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/root-equals-sum-of-children.rs) | [leetcode](https://leetcode-cn.com/problems/root-equals-sum-of-children/) | Easy | +|2386 | 极大极小游戏 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/min-max-game.rs) | [leetcode](https://leetcode-cn.com/problems/min-max-game/) | Easy | +|2392 | 咒语和药水的成功对数 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/successful-pairs-of-spells-and-potions.rs) | [leetcode](https://leetcode-cn.com/problems/successful-pairs-of-spells-and-potions/) | Medium | +|2413 | 无限集中的最小数字 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/smallest-number-in-infinite-set.rs) | [leetcode](https://leetcode-cn.com/problems/smallest-number-in-infinite-set/) | Medium | +|2414 | 移动片段得到字符串 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/move-pieces-to-obtain-a-string.rs) | [leetcode](https://leetcode-cn.com/problems/move-pieces-to-obtain-a-string/) | Medium | +|2442 | 算术三元组的数目 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/number-of-arithmetic-triplets.rs) | [leetcode](https://leetcode-cn.com/problems/number-of-arithmetic-triplets/) | Easy | +|2443 | 检查数组是否存在有效划分 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/check-if-there-is-a-valid-partition-for-the-array.rs) | [leetcode](https://leetcode-cn.com/problems/check-if-there-is-a-valid-partition-for-the-array/) | Medium | +|2461 | 感染二叉树需要的总时间 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/amount-of-time-for-binary-tree-to-be-infected.rs) | [leetcode](https://leetcode-cn.com/problems/amount-of-time-for-binary-tree-to-be-infected/) | Medium | +|2463 | 得到 K 个黑块的最少涂色次数 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/minimum-recolors-to-get-k-consecutive-black-blocks.rs) | [leetcode](https://leetcode-cn.com/problems/minimum-recolors-to-get-k-consecutive-black-blocks/) | Easy | +|2470 | 从字符串中移除星号 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/removing-stars-from-a-string.rs) | [leetcode](https://leetcode-cn.com/problems/removing-stars-from-a-string/) | Medium | +|2473 | 数位和相等数对的最大和 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/max-sum-of-a-pair-with-equal-sum-of-digits.rs) | [leetcode](https://leetcode-cn.com/problems/max-sum-of-a-pair-with-equal-sum-of-digits/) | Medium | +|2482 | 被列覆盖的最多行数 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/maximum-rows-covered-by-columns.rs) | [leetcode](https://leetcode-cn.com/problems/maximum-rows-covered-by-columns/) | Medium | +|2493 | 反转二叉树的奇数层 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/reverse-odd-levels-of-binary-tree.rs) | [leetcode](https://leetcode-cn.com/problems/reverse-odd-levels-of-binary-tree/) | Medium | +|2507 | 公因子的数目 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/number-of-common-factors.rs) | [leetcode](https://leetcode-cn.com/problems/number-of-common-factors/) | Easy | +|2509 | 最小异或 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/minimize-xor.rs) | [leetcode](https://leetcode-cn.com/problems/minimize-xor/) | Medium | +|2518 | 处理用时最长的那个任务的员工 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/the-employee-that-worked-on-the-longest-task.rs) | [leetcode](https://leetcode-cn.com/problems/the-employee-that-worked-on-the-longest-task/) | Easy | +|2519 | 找出前缀异或的原始数组 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/find-the-original-array-of-prefix-xor.rs) | [leetcode](https://leetcode-cn.com/problems/find-the-original-array-of-prefix-xor/) | Medium | +|2547 | 差值数组不同的字符串 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/odd-string-difference.rs) | [leetcode](https://leetcode-cn.com/problems/odd-string-difference/) | Easy | +|2551 | 对数组执行操作 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/apply-operations-to-an-array.rs) | [leetcode](https://leetcode-cn.com/problems/apply-operations-to-an-array/) | Easy | +|2566 | 数组中不等三元组的数目 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/number-of-unequal-triplets-in-array.rs) | [leetcode](https://leetcode-cn.com/problems/number-of-unequal-triplets-in-array/) | Easy | +|2567 | 二叉搜索树最近节点查询 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/closest-nodes-queries-in-a-binary-search-tree.rs) | [leetcode](https://leetcode-cn.com/problems/closest-nodes-queries-in-a-binary-search-tree/) | Medium | +|2571 | 找出中枢整数 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/find-the-pivot-integer.rs) | [leetcode](https://leetcode-cn.com/problems/find-the-pivot-integer/) | Easy | +|2573 | 从链表中移除节点 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/remove-nodes-from-linked-list.rs) | [leetcode](https://leetcode-cn.com/problems/remove-nodes-from-linked-list/) | Medium | +|2575 | 分割圆的最少切割次数 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/minimum-cuts-to-divide-a-circle.rs) | [leetcode](https://leetcode-cn.com/problems/minimum-cuts-to-divide-a-circle/) | Easy | +|2580 | 回环句 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/circular-sentence.rs) | [leetcode](https://leetcode-cn.com/problems/circular-sentence/) | Easy | +|2585 | 删除每行中的最大值 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/delete-greatest-value-in-each-row.rs) | [leetcode](https://leetcode-cn.com/problems/delete-greatest-value-in-each-row/) | Easy | +|2589 | 数组中字符串的最大值 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/maximum-value-of-a-string-in-an-array.rs) | [leetcode](https://leetcode-cn.com/problems/maximum-value-of-a-string-in-an-array/) | Easy | +|2602 | 最多可以摧毁的敌人城堡数目 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/maximum-enemy-forts-that-can-be-captured.rs) | [leetcode](https://leetcode-cn.com/problems/maximum-enemy-forts-that-can-be-captured/) | Easy | +|2603 | 奖励最顶尖的 K 名学生 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/reward-top-k-students.rs) | [leetcode](https://leetcode-cn.com/problems/reward-top-k-students/) | Medium | +|2608 | 统计能整除数字的位数 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/count-the-digits-that-divide-a-number.rs) | [leetcode](https://leetcode-cn.com/problems/count-the-digits-that-divide-a-number/) | Easy | +|2614 | 正整数和负整数的最大计数 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/maximum-count-of-positive-integer-and-negative-integer.rs) | [leetcode](https://leetcode-cn.com/problems/maximum-count-of-positive-integer-and-negative-integer/) | Easy | +|2616 | 执行 K 次操作后的最大分数 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/maximal-score-after-applying-k-operations.rs) | [leetcode](https://leetcode-cn.com/problems/maximal-score-after-applying-k-operations/) | Medium | +|2619 | 根据规则将箱子分类 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/categorize-box-according-to-criteria.rs) | [leetcode](https://leetcode-cn.com/problems/categorize-box-according-to-criteria/) | Easy | +|2621 | 查询数组异或美丽值 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/find-xor-beauty-of-array.rs) | [leetcode](https://leetcode-cn.com/problems/find-xor-beauty-of-array/) | Medium | +|2624 | 数组元素和与数字和的绝对差 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/difference-between-element-sum-and-digit-sum-of-an-array.rs) | [leetcode](https://leetcode-cn.com/problems/difference-between-element-sum-and-digit-sum-of-an-array/) | Easy | +|2625 | 子矩阵元素加 1 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/increment-submatrices-by-one.rs) | [leetcode](https://leetcode-cn.com/problems/increment-submatrices-by-one/) | Medium | +|2630 | 交替数字和 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/alternating-digit-sum.rs) | [leetcode](https://leetcode-cn.com/problems/alternating-digit-sum/) | Easy | +|2645 | 递枕头 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/pass-the-pillow.rs) | [leetcode](https://leetcode-cn.com/problems/pass-the-pillow/) | Easy | +|2646 | 二叉树中的第 K 大层和 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/kth-largest-sum-in-a-binary-tree.rs) | [leetcode](https://leetcode-cn.com/problems/kth-largest-sum-in-a-binary-tree/) | Medium | +|2650 | 最小和分割 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/split-with-minimum-sum.rs) | [leetcode](https://leetcode-cn.com/problems/split-with-minimum-sum/) | Easy | +|2651 | 统计将重叠区间合并成组的方案数 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/count-ways-to-group-overlapping-ranges.rs) | [leetcode](https://leetcode-cn.com/problems/count-ways-to-group-overlapping-ranges/) | Medium | +|2654 | 统计范围内的元音字符串数 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/count-the-number-of-vowel-strings-in-range.rs) | [leetcode](https://leetcode-cn.com/problems/count-the-number-of-vowel-strings-in-range/) | Easy | +|2662 | 检查骑士巡视方案 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/check-knight-tour-configuration.rs) | [leetcode](https://leetcode-cn.com/problems/check-knight-tour-configuration/) | Medium | +|2663 | 将钱分给最多的儿童 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/distribute-money-to-maximum-children.rs) | [leetcode](https://leetcode-cn.com/problems/distribute-money-to-maximum-children/) | Easy | +|2668 | 从两个数字数组里生成最小数字 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/form-smallest-number-from-two-digit-arrays.rs) | [leetcode](https://leetcode-cn.com/problems/form-smallest-number-from-two-digit-arrays/) | Easy | +|2668 | 从两个数字数组里生成最小数字 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/form-smallest-number-from-two-digit-arrays.rs) | [leetcode](https://leetcode-cn.com/problems/form-smallest-number-from-two-digit-arrays/) | Easy | +|2675 | 查询网格图中每一列的宽度 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/find-the-width-of-columns-of-a-grid.rs) | [leetcode](https://leetcode-cn.com/problems/find-the-width-of-columns-of-a-grid/) | Easy | +|2676 | 一个数组所有前缀的分数 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/find-the-score-of-all-prefixes-of-an-array.rs) | [leetcode](https://leetcode-cn.com/problems/find-the-score-of-all-prefixes-of-an-array/) | Medium | +|2679 | 统计桌面上的不同数字 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/count-distinct-numbers-on-board.rs) | [leetcode](https://leetcode-cn.com/problems/count-distinct-numbers-on-board/) | Easy | +|2684 | 保龄球游戏的获胜者 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/determine-the-winner-of-a-bowling-game.rs) | [leetcode](https://leetcode-cn.com/problems/determine-the-winner-of-a-bowling-game/) | Easy | +|2685 | 找出叠涂元素 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/first-completely-painted-row-or-column.rs) | [leetcode](https://leetcode-cn.com/problems/first-completely-painted-row-or-column/) | Medium | +|2691 | 统计范围内的元音字符串数 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/count-vowel-strings-in-ranges.rs) | [leetcode](https://leetcode-cn.com/problems/count-vowel-strings-in-ranges/) | Medium | +|2692 | 从数量最多的堆取走礼物 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/take-gifts-from-the-richest-pile.rs) | [leetcode](https://leetcode-cn.com/problems/take-gifts-from-the-richest-pile/) | Easy | +|2692 | 从数量最多的堆取走礼物 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/take-gifts-from-the-richest-pile.rs) | [leetcode](https://leetcode-cn.com/problems/take-gifts-from-the-richest-pile/) | Easy | +|2694 | 找出可整除性得分最大的整数 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/find-the-maximum-divisibility-score.rs) | [leetcode](https://leetcode-cn.com/problems/find-the-maximum-divisibility-score/) | Easy | +|2698 | 找出数组的串联值 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/find-the-array-concatenation-value.rs) | [leetcode](https://leetcode-cn.com/problems/find-the-array-concatenation-value/) | Easy | +|2704 | 替换一个数字后的最大差值 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/maximum-difference-by-remapping-a-digit.rs) | [leetcode](https://leetcode-cn.com/problems/maximum-difference-by-remapping-a-digit/) | Easy | +|2707 | 合并两个二维数组 - 求和法 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/merge-two-2d-arrays-by-summing-values.rs) | [leetcode](https://leetcode-cn.com/problems/merge-two-2d-arrays-by-summing-values/) | Easy | +|2713 | 找出字符串的可整除数组 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/find-the-divisibility-array-of-a-string.rs) | [leetcode](https://leetcode-cn.com/problems/find-the-divisibility-array-of-a-string/) | Medium | +|2715 | K 件物品的最大和 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/k-items-with-the-maximum-sum.rs) | [leetcode](https://leetcode-cn.com/problems/k-items-with-the-maximum-sum/) | Easy | +|2723 | 最长平衡子字符串 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/find-the-longest-balanced-substring-of-a-binary-string.rs) | [leetcode](https://leetcode-cn.com/problems/find-the-longest-balanced-substring-of-a-binary-string/) | Easy | +|2727 | 老人的数目 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/number-of-senior-citizens.rs) | [leetcode](https://leetcode-cn.com/problems/number-of-senior-citizens/) | Easy | +|2728 | 矩阵中的和 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/sum-in-a-matrix.rs) | [leetcode](https://leetcode-cn.com/problems/sum-in-a-matrix/) | Medium | +|2736 | 构造有效字符串的最少插入数 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/minimum-additions-to-make-valid-string.rs) | [leetcode](https://leetcode-cn.com/problems/minimum-additions-to-make-valid-string/) | Medium | +|2748 | 计算列车到站时间 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/calculate-delayed-arrival-time.rs) | [leetcode](https://leetcode-cn.com/problems/calculate-delayed-arrival-time/) | Easy | +|2752 | 倍数求和 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/sum-multiples.rs) | [leetcode](https://leetcode-cn.com/problems/sum-multiples/) | Easy | +|2755 | 字符串中的额外字符 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/extra-characters-in-a-string.rs) | [leetcode](https://leetcode-cn.com/problems/extra-characters-in-a-string/) | Medium | +|2756 | 购买两块巧克力 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/buy-two-chocolates.rs) | [leetcode](https://leetcode-cn.com/problems/buy-two-chocolates/) | Easy | +|2767 | K 个元素的最大和 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/maximum-sum-with-exactly-k-elements.rs) | [leetcode](https://leetcode-cn.com/problems/maximum-sum-with-exactly-k-elements/) | Easy | +|2777 | 找出不同元素数目差数组 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/find-the-distinct-difference-array.rs) | [leetcode](https://leetcode-cn.com/problems/find-the-distinct-difference-array/) | Easy | +|2778 | 频率跟踪器 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/frequency-tracker.rs) | [leetcode](https://leetcode-cn.com/problems/frequency-tracker/) | Medium | +|2780 | 使二叉树所有路径值相等的最小代价 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/make-costs-of-paths-equal-in-a-binary-tree.rs) | [leetcode](https://leetcode-cn.com/problems/make-costs-of-paths-equal-in-a-binary-tree/) | Medium | +|2787 | 移动机器人 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/movement-of-robots.rs) | [leetcode](https://leetcode-cn.com/problems/movement-of-robots/) | Medium | +|2791 | 找出转圈游戏输家 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/find-the-losers-of-the-circular-game.rs) | [leetcode](https://leetcode-cn.com/problems/find-the-losers-of-the-circular-game/) | Easy | +|2794 | 矩阵中移动的最大次数 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/maximum-number-of-moves-in-a-grid.rs) | [leetcode](https://leetcode-cn.com/problems/maximum-number-of-moves-in-a-grid/) | Medium | +|2800 | 删除子串后的字符串最小长度 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/minimum-string-length-after-removing-substrings.rs) | [leetcode](https://leetcode-cn.com/problems/minimum-string-length-after-removing-substrings/) | Easy | +|2802 | 求一个整数的惩罚数 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/find-the-punishment-number-of-an-integer.rs) | [leetcode](https://leetcode-cn.com/problems/find-the-punishment-number-of-an-integer/) | Medium | +|2812 | 找出最大的可达成数字 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/find-the-maximum-achievable-number.rs) | [leetcode](https://leetcode-cn.com/problems/find-the-maximum-achievable-number/) | Easy | +|2816 | 字典序最小回文串 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/lexicographically-smallest-palindrome.rs) | [leetcode](https://leetcode-cn.com/problems/lexicographically-smallest-palindrome/) | Easy | +|2819 | 移除字符串中的尾随零 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/remove-trailing-zeros-from-a-string.rs) | [leetcode](https://leetcode-cn.com/problems/remove-trailing-zeros-from-a-string/) | Easy | +|2828 | 执行子串操作后的字典序最小字符串 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/lexicographically-smallest-string-after-substring-operation.rs) | [leetcode](https://leetcode-cn.com/problems/lexicographically-smallest-string-after-substring-operation/) | Medium | +|2831 | 美丽下标对的数目 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/number-of-beautiful-pairs.rs) | [leetcode](https://leetcode-cn.com/problems/number-of-beautiful-pairs/) | Easy | +|2838 | 查询后矩阵的和 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/sum-of-matrix-after-queries.rs) | [leetcode](https://leetcode-cn.com/problems/sum-of-matrix-after-queries/) | Medium | +|2844 | 特殊元素平方和 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/sum-of-squares-of-special-elements.rs) | [leetcode](https://leetcode-cn.com/problems/sum-of-squares-of-special-elements/) | Easy | +|2847 | 最大字符串配对数目 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/find-maximum-number-of-string-pairs.rs) | [leetcode](https://leetcode-cn.com/problems/find-maximum-number-of-string-pairs/) | Easy | +|2857 | 总行驶距离 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/total-distance-traveled.rs) | [leetcode](https://leetcode-cn.com/problems/total-distance-traveled/) | Easy | +|2866 | 最长奇偶子数组 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/longest-even-odd-subarray-with-threshold.rs) | [leetcode](https://leetcode-cn.com/problems/longest-even-odd-subarray-with-threshold/) | Easy | +|2870 | 最长交替子数组 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/longest-alternating-subarray.rs) | [leetcode](https://leetcode-cn.com/problems/longest-alternating-subarray/) | Easy | +|2872 | 合并后数组中的最大元素 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/largest-element-in-an-array-after-merge-operations.rs) | [leetcode](https://leetcode-cn.com/problems/largest-element-in-an-array-after-merge-operations/) | Medium | +|2876 | 满足目标工作时长的员工数目 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/number-of-employees-who-met-the-target.rs) | [leetcode](https://leetcode-cn.com/problems/number-of-employees-who-met-the-target/) | Easy | +|2881 | 按分隔符拆分字符串 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/split-strings-by-separator.rs) | [leetcode](https://leetcode-cn.com/problems/split-strings-by-separator/) | Easy | +|2886 | 故障键盘 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/faulty-keyboard.rs) | [leetcode](https://leetcode-cn.com/problems/faulty-keyboard/) | Easy | +|2893 | 访问数组中的位置使分数最大 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/visit-array-positions-to-maximize-score.rs) | [leetcode](https://leetcode-cn.com/problems/visit-array-positions-to-maximize-score/) | Medium | +|2917 | 统计和小于目标的下标对数目 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/count-pairs-whose-sum-is-less-than-target.rs) | [leetcode](https://leetcode-cn.com/problems/count-pairs-whose-sum-is-less-than-target/) | Easy | +|2920 | 使循环数组所有元素相等的最少秒数 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/minimum-seconds-to-equalize-a-circular-array.rs) | [leetcode](https://leetcode-cn.com/problems/minimum-seconds-to-equalize-a-circular-array/) | Medium | +|2954 | 几乎唯一子数组的最大和 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/maximum-sum-of-almost-unique-subarray.rs) | [leetcode](https://leetcode-cn.com/problems/maximum-sum-of-almost-unique-subarray/) | Medium | +|2955 | 取整购买后的账户余额 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/account-balance-after-rounded-purchase.rs) | [leetcode](https://leetcode-cn.com/problems/account-balance-after-rounded-purchase/) | Easy | +|2977 | 判别首字母缩略词 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/check-if-a-string-is-an-acronym-of-words.rs) | [leetcode](https://leetcode-cn.com/problems/check-if-a-string-is-an-acronym-of-words/) | Easy | +|3026 | 找出美丽数组的最小和 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/find-the-minimum-possible-sum-of-a-beautiful-array.rs) | [leetcode](https://leetcode-cn.com/problems/find-the-minimum-possible-sum-of-a-beautiful-array/) | Medium | +|3045 | 使数组成为递增数组的最少右移次数 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/minimum-right-shifts-to-sort-the-array.rs) | [leetcode](https://leetcode-cn.com/problems/minimum-right-shifts-to-sort-the-array/) | Easy | +|3046 | 生成特殊数字的最少操作 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/minimum-operations-to-make-a-special-number.rs) | [leetcode](https://leetcode-cn.com/problems/minimum-operations-to-make-a-special-number/) | Medium | +|3055 | 最大二进制奇数 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/maximum-odd-binary-number.rs) | [leetcode](https://leetcode-cn.com/problems/maximum-odd-binary-number/) | Easy | +|3093 | 计算 K 置位下标对应元素的和 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/sum-of-values-at-indices-with-k-set-bits.rs) | [leetcode](https://leetcode-cn.com/problems/sum-of-values-at-indices-with-k-set-bits/) | Easy | +|3094 | 使数组为空的最少操作次数 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/minimum-number-of-operations-to-make-array-empty.rs) | [leetcode](https://leetcode-cn.com/problems/minimum-number-of-operations-to-make-array-empty/) | Medium | +|3095 | 最大合金数 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/maximum-number-of-alloys.rs) | [leetcode](https://leetcode-cn.com/problems/maximum-number-of-alloys/) | Medium | +|3152 | 有序三元组中的最大值 II | [src](https://github.com/rustors/leetcode/blob/main/src/bin/maximum-value-of-an-ordered-triplet-ii.rs) | [leetcode](https://leetcode-cn.com/problems/maximum-value-of-an-ordered-triplet-ii/) | Medium | +|3165 | 找出满足差值条件的下标 I | [src](https://github.com/rustors/leetcode/blob/main/src/bin/find-indices-with-index-and-value-difference-i.rs) | [leetcode](https://leetcode-cn.com/problems/find-indices-with-index-and-value-difference-i/) | Easy | +|3176 | 元素和最小的山形三元组 I | [src](https://github.com/rustors/leetcode/blob/main/src/bin/minimum-sum-of-mountain-triplets-i.rs) | [leetcode](https://leetcode-cn.com/problems/minimum-sum-of-mountain-triplets-i/) | Easy | +|3183 | 找出数组中的 K-or 值 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/find-the-k-or-of-an-array.rs) | [leetcode](https://leetcode-cn.com/problems/find-the-k-or-of-an-array/) | Easy | +|3188 | 找到冠军 I | [src](https://github.com/rustors/leetcode/blob/main/src/bin/find-champion-i.rs) | [leetcode](https://leetcode-cn.com/problems/find-champion-i/) | Easy | +|3189 | 找到冠军 II | [src](https://github.com/rustors/leetcode/blob/main/src/bin/find-champion-ii.rs) | [leetcode](https://leetcode-cn.com/problems/find-champion-ii/) | Medium | +|3195 | 区分黑球与白球 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/separate-black-and-white-balls.rs) | [leetcode](https://leetcode-cn.com/problems/separate-black-and-white-balls/) | Medium | +|3199 | 给小朋友们分糖果 I | [src](https://github.com/rustors/leetcode/blob/main/src/bin/distribute-candies-among-children-i.rs) | [leetcode](https://leetcode-cn.com/problems/distribute-candies-among-children-i/) | Easy | +|3206 | 找到两个数组中的公共元素 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/find-common-elements-between-two-arrays.rs) | [leetcode](https://leetcode-cn.com/problems/find-common-elements-between-two-arrays/) | Easy | +|3207 | 使三个字符串相等 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/make-three-strings-equal.rs) | [leetcode](https://leetcode-cn.com/problems/make-three-strings-equal/) | Easy | +|3220 | 统计已测试设备 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/count-tested-devices-after-test-operations.rs) | [leetcode](https://leetcode-cn.com/problems/count-tested-devices-after-test-operations/) | Easy | +|3221 | 找出峰值 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/find-the-peaks.rs) | [leetcode](https://leetcode-cn.com/problems/find-the-peaks/) | Easy | +|3226 | 最小数字游戏 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/minimum-number-game.rs) | [leetcode](https://leetcode-cn.com/problems/minimum-number-game/) | Easy | +|3227 | 找出缺失和重复的数字 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/find-missing-and-repeated-values.rs) | [leetcode](https://leetcode-cn.com/problems/find-missing-and-repeated-values/) | Easy | +|3228 | 移除后集合的最多元素数 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/maximum-size-of-a-set-after-removals.rs) | [leetcode](https://leetcode-cn.com/problems/maximum-size-of-a-set-after-removals/) | Medium | +|3231 | 需要添加的硬币的最小数量 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/minimum-number-of-coins-to-be-added.rs) | [leetcode](https://leetcode-cn.com/problems/minimum-number-of-coins-to-be-added/) | Medium | +|3234 | 双模幂运算 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/double-modular-exponentiation.rs) | [leetcode](https://leetcode-cn.com/problems/double-modular-exponentiation/) | Medium | +|3241 | 划分数组并满足最大差限制 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/divide-array-into-arrays-with-max-difference.rs) | [leetcode](https://leetcode-cn.com/problems/divide-array-into-arrays-with-max-difference/) | Medium | +|3265 | 最大好子数组和 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/maximum-good-subarray-sum.rs) | [leetcode](https://leetcode-cn.com/problems/maximum-good-subarray-sum/) | Medium | +|3275 | 输入单词需要的最少按键次数 I | [src](https://github.com/rustors/leetcode/blob/main/src/bin/minimum-number-of-pushes-to-type-word-i.rs) | [leetcode](https://leetcode-cn.com/problems/minimum-number-of-pushes-to-type-word-i/) | Easy | +|3320 | 相同分数的最大操作数目 I | [src](https://github.com/rustors/leetcode/blob/main/src/bin/maximum-number-of-operations-with-the-same-score-i.rs) | [leetcode](https://leetcode-cn.com/problems/maximum-number-of-operations-with-the-same-score-i/) | Easy | +|3330 | 修改矩阵 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/modify-the-matrix.rs) | [leetcode](https://leetcode-cn.com/problems/modify-the-matrix/) | Easy | +|3331 | 超过阈值的最少操作数 I | [src](https://github.com/rustors/leetcode/blob/main/src/bin/minimum-operations-to-exceed-threshold-value-i.rs) | [leetcode](https://leetcode-cn.com/problems/minimum-operations-to-exceed-threshold-value-i/) | Easy | +|3334 | 重新分装苹果 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/apple-redistribution-into-boxes.rs) | [leetcode](https://leetcode-cn.com/problems/apple-redistribution-into-boxes/) | Easy | +|3346 | 满足距离约束且字典序最小的字符串 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/lexicographically-smallest-string-after-operations-with-constraint.rs) | [leetcode](https://leetcode-cn.com/problems/lexicographically-smallest-string-after-operations-with-constraint/) | Medium | +|3347 | 将元素分配到两个数组中 I | [src](https://github.com/rustors/leetcode/blob/main/src/bin/distribute-elements-into-two-arrays-i.rs) | [leetcode](https://leetcode-cn.com/problems/distribute-elements-into-two-arrays-i/) | Easy | +|3371 | 哈沙德数 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/harshad-number.rs) | [leetcode](https://leetcode-cn.com/problems/harshad-number/) | Easy | +|3373 | 质数的最大距离 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/maximum-prime-difference.rs) | [leetcode](https://leetcode-cn.com/problems/maximum-prime-difference/) | Medium | +|3374 | 交替子数组计数 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/count-alternating-subarrays.rs) | [leetcode](https://leetcode-cn.com/problems/count-alternating-subarrays/) | Medium | +|3388 | 直角三角形 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/right-triangles.rs) | [leetcode](https://leetcode-cn.com/problems/right-triangles/) | Medium | +|3390 | 覆盖所有点的最少矩形数目 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/minimum-rectangles-to-cover-points.rs) | [leetcode](https://leetcode-cn.com/problems/minimum-rectangles-to-cover-points/) | Medium | +|3397 | 找出与数组相加的整数 I | [src](https://github.com/rustors/leetcode/blob/main/src/bin/find-the-integer-added-to-array-i.rs) | [leetcode](https://leetcode-cn.com/problems/find-the-integer-added-to-array-i/) | Easy | +|3412 | 两个字符串的排列差 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/permutation-difference-between-two-strings.rs) | [leetcode](https://leetcode-cn.com/problems/permutation-difference-between-two-strings/) | Easy | +|3415 | 判断矩阵是否满足条件 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/check-if-grid-satisfies-conditions.rs) | [leetcode](https://leetcode-cn.com/problems/check-if-grid-satisfies-conditions/) | Easy | +|3427 | 特殊数组 II | [src](https://github.com/rustors/leetcode/blob/main/src/bin/special-array-ii.rs) | [leetcode](https://leetcode-cn.com/problems/special-array-ii/) | Medium | +|3429 | 特殊数组 I | [src](https://github.com/rustors/leetcode/blob/main/src/bin/special-array-i.rs) | [leetcode](https://leetcode-cn.com/problems/special-array-i/) | Easy | +|100160 | URL化 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/string-to-url-lcci.rs) | [leetcode](https://leetcode-cn.com/problems/string-to-url-lcci/) | Easy | +|100162 | 字符串轮转 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/string-rotation-lcci.rs) | [leetcode](https://leetcode-cn.com/problems/string-rotation-lcci/) | Easy | +|100163 | 移除重复节点 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/remove-duplicate-node-lcci.rs) | [leetcode](https://leetcode-cn.com/problems/remove-duplicate-node-lcci/) | Easy | +|100188 | 链表求和 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/sum-lists-lcci.rs) | [leetcode](https://leetcode-cn.com/problems/sum-lists-lcci/) | Medium | +|100240 | 魔术索引 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/magic-index-lcci.rs) | [leetcode](https://leetcode-cn.com/problems/magic-index-lcci/) | Easy | +|100273 | 用两个栈实现队列 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/yong-liang-ge-zhan-shi-xian-dui-lie-lcof.rs) | [leetcode](https://leetcode-cn.com/problems/yong-liang-ge-zhan-shi-xian-dui-lie-lcof/) | Easy | +|100274 | 斐波那契数列 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/fei-bo-na-qi-shu-lie-lcof.rs) | [leetcode](https://leetcode-cn.com/problems/fei-bo-na-qi-shu-lie-lcof/) | Easy | +|100275 | 数组中重复的数字 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/shu-zu-zhong-zhong-fu-de-shu-zi-lcof.rs) | [leetcode](https://leetcode-cn.com/problems/shu-zu-zhong-zhong-fu-de-shu-zi-lcof/) | Easy | +|100276 | 二维数组中的查找 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/er-wei-shu-zu-zhong-de-cha-zhao-lcof.rs) | [leetcode](https://leetcode-cn.com/problems/er-wei-shu-zu-zhong-de-cha-zhao-lcof/) | Medium | +|100277 | 青蛙跳台阶问题 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/qing-wa-tiao-tai-jie-wen-ti-lcof.rs) | [leetcode](https://leetcode-cn.com/problems/qing-wa-tiao-tai-jie-wen-ti-lcof/) | Easy | +|100278 | 旋转数组的最小数字 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/xuan-zhuan-shu-zu-de-zui-xiao-shu-zi-lcof.rs) | [leetcode](https://leetcode-cn.com/problems/xuan-zhuan-shu-zu-de-zui-xiao-shu-zi-lcof/) | Easy | +|100279 | 矩阵中的路径 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/ju-zhen-zhong-de-lu-jing-lcof.rs) | [leetcode](https://leetcode-cn.com/problems/ju-zhen-zhong-de-lu-jing-lcof/) | Medium | +|100280 | 替换空格 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/ti-huan-kong-ge-lcof.rs) | [leetcode](https://leetcode-cn.com/problems/ti-huan-kong-ge-lcof/) | Easy | +|100281 | 机器人的运动范围 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/ji-qi-ren-de-yun-dong-fan-wei-lcof.rs) | [leetcode](https://leetcode-cn.com/problems/ji-qi-ren-de-yun-dong-fan-wei-lcof/) | Medium | +|100282 | 从尾到头打印链表 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/cong-wei-dao-tou-da-yin-lian-biao-lcof.rs) | [leetcode](https://leetcode-cn.com/problems/cong-wei-dao-tou-da-yin-lian-biao-lcof/) | Easy | +|100283 | 重建二叉树 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/zhong-jian-er-cha-shu-lcof.rs) | [leetcode](https://leetcode-cn.com/problems/zhong-jian-er-cha-shu-lcof/) | Medium | +|100284 | 剪绳子 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/jian-sheng-zi-lcof.rs) | [leetcode](https://leetcode-cn.com/problems/jian-sheng-zi-lcof/) | Medium | +|100285 | 剪绳子 II | [src](https://github.com/rustors/leetcode/blob/main/src/bin/jian-sheng-zi-ii-lcof.rs) | [leetcode](https://leetcode-cn.com/problems/jian-sheng-zi-ii-lcof/) | Medium | +|100286 | 合并两个排序的链表 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/he-bing-liang-ge-pai-xu-de-lian-biao-lcof.rs) | [leetcode](https://leetcode-cn.com/problems/he-bing-liang-ge-pai-xu-de-lian-biao-lcof/) | Easy | +|100287 | 树的子结构 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/shu-de-zi-jie-gou-lcof.rs) | [leetcode](https://leetcode-cn.com/problems/shu-de-zi-jie-gou-lcof/) | Medium | +|100288 | 二叉树的镜像 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/er-cha-shu-de-jing-xiang-lcof.rs) | [leetcode](https://leetcode-cn.com/problems/er-cha-shu-de-jing-xiang-lcof/) | Easy | +|100289 | 对称的二叉树 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/dui-cheng-de-er-cha-shu-lcof.rs) | [leetcode](https://leetcode-cn.com/problems/dui-cheng-de-er-cha-shu-lcof/) | Easy | +|100290 | 表示数值的字符串 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/biao-shi-shu-zhi-de-zi-fu-chuan-lcof.rs) | [leetcode](https://leetcode-cn.com/problems/biao-shi-shu-zhi-de-zi-fu-chuan-lcof/) | Medium | +|100291 | 调整数组顺序使奇数位于偶数前面 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/diao-zheng-shu-zu-shun-xu-shi-qi-shu-wei-yu-ou-shu-qian-mian-lcof.rs) | [leetcode](https://leetcode-cn.com/problems/diao-zheng-shu-zu-shun-xu-shi-qi-shu-wei-yu-ou-shu-qian-mian-lcof/) | Easy | +|100292 | 二进制中1的个数 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/er-jin-zhi-zhong-1de-ge-shu-lcof.rs) | [leetcode](https://leetcode-cn.com/problems/er-jin-zhi-zhong-1de-ge-shu-lcof/) | Easy | +|100293 | 顺时针打印矩阵 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/shun-shi-zhen-da-yin-ju-zhen-lcof.rs) | [leetcode](https://leetcode-cn.com/problems/shun-shi-zhen-da-yin-ju-zhen-lcof/) | Easy | +|100294 | 链表中倒数第k个节点 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/lian-biao-zhong-dao-shu-di-kge-jie-dian-lcof.rs) | [leetcode](https://leetcode-cn.com/problems/lian-biao-zhong-dao-shu-di-kge-jie-dian-lcof/) | Easy | +|100295 | 数值的整数次方 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/shu-zhi-de-zheng-shu-ci-fang-lcof.rs) | [leetcode](https://leetcode-cn.com/problems/shu-zhi-de-zheng-shu-ci-fang-lcof/) | Medium | +|100295 | 数值的整数次方 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/shu-zhi-de-zheng-shu-ci-fang-lcof.rs) | [leetcode](https://leetcode-cn.com/problems/shu-zhi-de-zheng-shu-ci-fang-lcof/) | Medium | +|100296 | 打印从1到最大的n位数 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/da-yin-cong-1dao-zui-da-de-nwei-shu-lcof.rs) | [leetcode](https://leetcode-cn.com/problems/da-yin-cong-1dao-zui-da-de-nwei-shu-lcof/) | Easy | +|100296 | 打印从1到最大的n位数 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/da-yin-cong-1dao-zui-da-de-nwei-shu-lcof.rs) | [leetcode](https://leetcode-cn.com/problems/da-yin-cong-1dao-zui-da-de-nwei-shu-lcof/) | Easy | +|100298 | 反转链表 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/fan-zhuan-lian-biao-lcof.rs) | [leetcode](https://leetcode-cn.com/problems/fan-zhuan-lian-biao-lcof/) | Easy | +|100299 | 删除链表的节点 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/shan-chu-lian-biao-de-jie-dian-lcof.rs) | [leetcode](https://leetcode-cn.com/problems/shan-chu-lian-biao-de-jie-dian-lcof/) | Easy | +|100301 | 最小的k个数 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/zui-xiao-de-kge-shu-lcof.rs) | [leetcode](https://leetcode-cn.com/problems/zui-xiao-de-kge-shu-lcof/) | Easy | +|100302 | 包含min函数的栈 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/bao-han-minhan-shu-de-zhan-lcof.rs) | [leetcode](https://leetcode-cn.com/problems/bao-han-minhan-shu-de-zhan-lcof/) | Easy | +|100303 | 数据流中的中位数 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/shu-ju-liu-zhong-de-zhong-wei-shu-lcof.rs) | [leetcode](https://leetcode-cn.com/problems/shu-ju-liu-zhong-de-zhong-wei-shu-lcof/) | Hard | +|100304 | 连续子数组的最大和 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/lian-xu-zi-shu-zu-de-zui-da-he-lcof.rs) | [leetcode](https://leetcode-cn.com/problems/lian-xu-zi-shu-zu-de-zui-da-he-lcof/) | Easy | +|100306 | 栈的压入、弹出序列 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/zhan-de-ya-ru-dan-chu-xu-lie-lcof.rs) | [leetcode](https://leetcode-cn.com/problems/zhan-de-ya-ru-dan-chu-xu-lie-lcof/) | Medium | +|100308 | 字符串的排列 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/zi-fu-chuan-de-pai-lie-lcof.rs) | [leetcode](https://leetcode-cn.com/problems/zi-fu-chuan-de-pai-lie-lcof/) | Medium | +|100308 | 字符串的排列 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/zi-fu-chuan-de-pai-lie-lcof.rs) | [leetcode](https://leetcode-cn.com/problems/zi-fu-chuan-de-pai-lie-lcof/) | Medium | +|100309 | 1~n 整数中 1 出现的次数 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/1nzheng-shu-zhong-1chu-xian-de-ci-shu-lcof.rs) | [leetcode](https://leetcode-cn.com/problems/1nzheng-shu-zhong-1chu-xian-de-ci-shu-lcof/) | Hard | +|100310 | 数组中出现次数超过一半的数字 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/shu-zu-zhong-chu-xian-ci-shu-chao-guo-yi-ban-de-shu-zi-lcof.rs) | [leetcode](https://leetcode-cn.com/problems/shu-zu-zhong-chu-xian-ci-shu-chao-guo-yi-ban-de-shu-zi-lcof/) | Easy | +|100311 | 从上到下打印二叉树 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/cong-shang-dao-xia-da-yin-er-cha-shu-lcof.rs) | [leetcode](https://leetcode-cn.com/problems/cong-shang-dao-xia-da-yin-er-cha-shu-lcof/) | Medium | +|100312 | 从上到下打印二叉树 II | [src](https://github.com/rustors/leetcode/blob/main/src/bin/cong-shang-dao-xia-da-yin-er-cha-shu-ii-lcof.rs) | [leetcode](https://leetcode-cn.com/problems/cong-shang-dao-xia-da-yin-er-cha-shu-ii-lcof/) | Easy | +|100313 | 数字序列中某一位的数字 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/shu-zi-xu-lie-zhong-mou-yi-wei-de-shu-zi-lcof.rs) | [leetcode](https://leetcode-cn.com/problems/shu-zi-xu-lie-zhong-mou-yi-wei-de-shu-zi-lcof/) | Medium | +|100314 | 从上到下打印二叉树 III | [src](https://github.com/rustors/leetcode/blob/main/src/bin/cong-shang-dao-xia-da-yin-er-cha-shu-iii-lcof.rs) | [leetcode](https://leetcode-cn.com/problems/cong-shang-dao-xia-da-yin-er-cha-shu-iii-lcof/) | Medium | +|100315 | 二叉搜索树的后序遍历序列 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/er-cha-sou-suo-shu-de-hou-xu-bian-li-xu-lie-lcof.rs) | [leetcode](https://leetcode-cn.com/problems/er-cha-sou-suo-shu-de-hou-xu-bian-li-xu-lie-lcof/) | Medium | +|100316 | 第一个只出现一次的字符 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/di-yi-ge-zhi-chu-xian-yi-ci-de-zi-fu-lcof.rs) | [leetcode](https://leetcode-cn.com/problems/di-yi-ge-zhi-chu-xian-yi-ci-de-zi-fu-lcof/) | Easy | +|100317 | 二叉树中和为某一值的路径 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/er-cha-shu-zhong-he-wei-mou-yi-zhi-de-lu-jing-lcof.rs) | [leetcode](https://leetcode-cn.com/problems/er-cha-shu-zhong-he-wei-mou-yi-zhi-de-lu-jing-lcof/) | Medium | +|100318 | 数组中的逆序对 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/shu-zu-zhong-de-ni-xu-dui-lcof.rs) | [leetcode](https://leetcode-cn.com/problems/shu-zu-zhong-de-ni-xu-dui-lcof/) | Hard | +|100319 | 二叉树的深度 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/er-cha-shu-de-shen-du-lcof.rs) | [leetcode](https://leetcode-cn.com/problems/er-cha-shu-de-shen-du-lcof/) | Easy | +|100319 | 二叉树的深度 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/er-cha-shu-de-shen-du-lcof.rs) | [leetcode](https://leetcode-cn.com/problems/er-cha-shu-de-shen-du-lcof/) | Easy | +|100320 | 数组中数字出现的次数 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/shu-zu-zhong-shu-zi-chu-xian-de-ci-shu-lcof.rs) | [leetcode](https://leetcode-cn.com/problems/shu-zu-zhong-shu-zi-chu-xian-de-ci-shu-lcof/) | Medium | +|100321 | 数组中数字出现的次数 II | [src](https://github.com/rustors/leetcode/blob/main/src/bin/shu-zu-zhong-shu-zi-chu-xian-de-ci-shu-ii-lcof.rs) | [leetcode](https://leetcode-cn.com/problems/shu-zu-zhong-shu-zi-chu-xian-de-ci-shu-ii-lcof/) | Medium | +|100322 | 和为s的两个数字 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/he-wei-sde-liang-ge-shu-zi-lcof.rs) | [leetcode](https://leetcode-cn.com/problems/he-wei-sde-liang-ge-shu-zi-lcof/) | Easy | +|100323 | 把数组排成最小的数 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/ba-shu-zu-pai-cheng-zui-xiao-de-shu-lcof.rs) | [leetcode](https://leetcode-cn.com/problems/ba-shu-zu-pai-cheng-zui-xiao-de-shu-lcof/) | Medium | +|100324 | 和为s的连续正数序列 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/he-wei-sde-lian-xu-zheng-shu-xu-lie-lcof.rs) | [leetcode](https://leetcode-cn.com/problems/he-wei-sde-lian-xu-zheng-shu-xu-lie-lcof/) | Easy | +|100325 | 把数字翻译成字符串 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/ba-shu-zi-fan-yi-cheng-zi-fu-chuan-lcof.rs) | [leetcode](https://leetcode-cn.com/problems/ba-shu-zi-fan-yi-cheng-zi-fu-chuan-lcof/) | Medium | +|100325 | 把数字翻译成字符串 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/ba-shu-zi-fan-yi-cheng-zi-fu-chuan-lcof.rs) | [leetcode](https://leetcode-cn.com/problems/ba-shu-zi-fan-yi-cheng-zi-fu-chuan-lcof/) | Medium | +|100327 | 礼物的最大价值 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/li-wu-de-zui-da-jie-zhi-lcof.rs) | [leetcode](https://leetcode-cn.com/problems/li-wu-de-zui-da-jie-zhi-lcof/) | Medium | +|100328 | 翻转单词顺序 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/fan-zhuan-dan-ci-shun-xu-lcof.rs) | [leetcode](https://leetcode-cn.com/problems/fan-zhuan-dan-ci-shun-xu-lcof/) | Easy | +|100329 | 在排序数组中查找数字 I | [src](https://github.com/rustors/leetcode/blob/main/src/bin/zai-pai-xu-shu-zu-zhong-cha-zhao-shu-zi-lcof.rs) | [leetcode](https://leetcode-cn.com/problems/zai-pai-xu-shu-zu-zhong-cha-zhao-shu-zi-lcof/) | Easy | +|100330 | 左旋转字符串 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/zuo-xuan-zhuan-zi-fu-chuan-lcof.rs) | [leetcode](https://leetcode-cn.com/problems/zuo-xuan-zhuan-zi-fu-chuan-lcof/) | Easy | +|100331 | 0~n-1中缺失的数字 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/que-shi-de-shu-zi-lcof.rs) | [leetcode](https://leetcode-cn.com/problems/que-shi-de-shu-zi-lcof/) | Easy | +|100332 | 最长不含重复字符的子字符串 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/zui-chang-bu-han-zhong-fu-zi-fu-de-zi-zi-fu-chuan-lcof.rs) | [leetcode](https://leetcode-cn.com/problems/zui-chang-bu-han-zhong-fu-zi-fu-de-zi-zi-fu-chuan-lcof/) | Medium | +|100333 | 二叉搜索树的第k大节点 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/er-cha-sou-suo-shu-de-di-kda-jie-dian-lcof.rs) | [leetcode](https://leetcode-cn.com/problems/er-cha-sou-suo-shu-de-di-kda-jie-dian-lcof/) | Easy | +|100334 | 丑数 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/chou-shu-lcof.rs) | [leetcode](https://leetcode-cn.com/problems/chou-shu-lcof/) | Medium | +|100335 | 不用加减乘除做加法 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/bu-yong-jia-jian-cheng-chu-zuo-jia-fa-lcof.rs) | [leetcode](https://leetcode-cn.com/problems/bu-yong-jia-jian-cheng-chu-zuo-jia-fa-lcof/) | Easy | +|100337 | 队列的最大值 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/dui-lie-de-zui-da-zhi-lcof.rs) | [leetcode](https://leetcode-cn.com/problems/dui-lie-de-zui-da-zhi-lcof/) | Medium | +|100338 | 构建乘积数组 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/gou-jian-cheng-ji-shu-zu-lcof.rs) | [leetcode](https://leetcode-cn.com/problems/gou-jian-cheng-ji-shu-zu-lcof/) | Medium | +|100339 | n个骰子的点数 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/nge-tou-zi-de-dian-shu-lcof.rs) | [leetcode](https://leetcode-cn.com/problems/nge-tou-zi-de-dian-shu-lcof/) | Medium | +|100340 | 把字符串转换成整数 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/ba-zi-fu-chuan-zhuan-huan-cheng-zheng-shu-lcof.rs) | [leetcode](https://leetcode-cn.com/problems/ba-zi-fu-chuan-zhuan-huan-cheng-zheng-shu-lcof/) | Medium | +|100341 | 扑克牌中的顺子 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/bu-ke-pai-zhong-de-shun-zi-lcof.rs) | [leetcode](https://leetcode-cn.com/problems/bu-ke-pai-zhong-de-shun-zi-lcof/) | Easy | +|100342 | 平衡二叉树 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/ping-heng-er-cha-shu-lcof.rs) | [leetcode](https://leetcode-cn.com/problems/ping-heng-er-cha-shu-lcof/) | Easy | +|100342 | 平衡二叉树 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/ping-heng-er-cha-shu-lcof.rs) | [leetcode](https://leetcode-cn.com/problems/ping-heng-er-cha-shu-lcof/) | Easy | +|100343 | 圆圈中最后剩下的数字 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/yuan-quan-zhong-zui-hou-sheng-xia-de-shu-zi-lcof.rs) | [leetcode](https://leetcode-cn.com/problems/yuan-quan-zhong-zui-hou-sheng-xia-de-shu-zi-lcof/) | Easy | +|100344 | 股票的最大利润 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/gu-piao-de-zui-da-li-run-lcof.rs) | [leetcode](https://leetcode-cn.com/problems/gu-piao-de-zui-da-li-run-lcof/) | Medium | +|100345 | 求1+2+…+n | [src](https://github.com/rustors/leetcode/blob/main/src/bin/qiu-12n-lcof.rs) | [leetcode](https://leetcode-cn.com/problems/qiu-12n-lcof/) | Medium | +|100349 | 最大数值 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/maximum-lcci.rs) | [leetcode](https://leetcode-cn.com/problems/maximum-lcci/) | Easy | +|100351 | 生存人数 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/living-people-lcci.rs) | [leetcode](https://leetcode-cn.com/problems/living-people-lcci/) | Medium | +|100352 | 跳水板 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/diving-board-lcci.rs) | [leetcode](https://leetcode-cn.com/problems/diving-board-lcci/) | Easy | +|100353 | 平分正方形 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/bisect-squares-lcci.rs) | [leetcode](https://leetcode-cn.com/problems/bisect-squares-lcci/) | Medium | +|100355 | 珠玑妙算 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/master-mind-lcci.rs) | [leetcode](https://leetcode-cn.com/problems/master-mind-lcci/) | Easy | +|1000021 | 最小K个数 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/smallest-k-lcci.rs) | [leetcode](https://leetcode-cn.com/problems/smallest-k-lcci/) | Medium | +|1000022 | 最长单词 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/longest-word-lcci.rs) | [leetcode](https://leetcode-cn.com/problems/longest-word-lcci/) | Medium | +|1000025 | 不用加号的加法 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/add-without-plus-lcci.rs) | [leetcode](https://leetcode-cn.com/problems/add-without-plus-lcci/) | Easy | +|1000056 | 拿硬币 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/na-ying-bi.rs) | [leetcode](https://leetcode-cn.com/problems/na-ying-bi/) | Easy | +|1000063 | 传递信息 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/chuan-di-xin-xi.rs) | [leetcode](https://leetcode-cn.com/problems/chuan-di-xin-xi/) | Easy | +|1000139 | 速算机器人 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/nGK0Fy.rs) | [leetcode](https://leetcode-cn.com/problems/nGK0Fy/) | Easy | +|1000224 | 魔塔游戏 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/p0NxJO.rs) | [leetcode](https://leetcode-cn.com/problems/p0NxJO/) | Medium | +|1000225 | 下载插件 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/Ju9Xwi.rs) | [leetcode](https://leetcode-cn.com/problems/Ju9Xwi/) | Easy | +|1000228 | 整数除法 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/xoh6Oh.rs) | [leetcode](https://leetcode-cn.com/problems/xoh6Oh/) | Easy | +|1000230 | 前 n 个数字二进制中 1 的个数 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/w3tCBm.rs) | [leetcode](https://leetcode-cn.com/problems/w3tCBm/) | Easy | +|1000231 | 二进制加法 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/JFETK5.rs) | [leetcode](https://leetcode-cn.com/problems/JFETK5/) | Easy | +|1000233 | 只出现一次的数字 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/WGki4K.rs) | [leetcode](https://leetcode-cn.com/problems/WGki4K/) | Medium | +|1000236 | 单词长度的最大乘积 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/aseY1I.rs) | [leetcode](https://leetcode-cn.com/problems/aseY1I/) | Medium | +|1000237 | 排序数组中两个数字之和 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/kLl5u1.rs) | [leetcode](https://leetcode-cn.com/problems/kLl5u1/) | Easy | +|1000238 | 括号生成 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/IDBivT.rs) | [leetcode](https://leetcode-cn.com/problems/IDBivT/) | Medium | +|1000242 | 和大于等于 target 的最短子数组 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/2VG8Kg.rs) | [leetcode](https://leetcode-cn.com/problems/2VG8Kg/) | Medium | +|1000244 | 乘积小于 K 的子数组 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/ZVAVXX.rs) | [leetcode](https://leetcode-cn.com/problems/ZVAVXX/) | Medium | +|1000246 | 和为 k 的子数组 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/QTMn0o.rs) | [leetcode](https://leetcode-cn.com/problems/QTMn0o/) | Medium | +|1000247 | 0 和 1 个数相同的子数组 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/A1NYOS.rs) | [leetcode](https://leetcode-cn.com/problems/A1NYOS/) | Medium | +|1000248 | 左右两边子数组的和相等 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/tvdfij.rs) | [leetcode](https://leetcode-cn.com/problems/tvdfij/) | Easy | +|1000249 | 二维子矩阵的和 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/O4NDxx.rs) | [leetcode](https://leetcode-cn.com/problems/O4NDxx/) | Medium | +|1000250 | 字符串中的变位词 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/MPnaiL.rs) | [leetcode](https://leetcode-cn.com/problems/MPnaiL/) | Medium | +|1000251 | 字符串中的所有变位词 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/VabMRr.rs) | [leetcode](https://leetcode-cn.com/problems/VabMRr/) | Medium | +|1000252 | 不含重复字符的最长子字符串 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/wtcaE1.rs) | [leetcode](https://leetcode-cn.com/problems/wtcaE1/) | Medium | +|1000254 | 有效的回文 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/XltzEq.rs) | [leetcode](https://leetcode-cn.com/problems/XltzEq/) | Easy | +|1000255 | 最多删除一个字符得到回文 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/RQku0D.rs) | [leetcode](https://leetcode-cn.com/problems/RQku0D/) | Easy | +|1000256 | 回文子字符串的个数 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/a7VOhD.rs) | [leetcode](https://leetcode-cn.com/problems/a7VOhD/) | Medium | +|1000261 | 链表中的两数相加 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/lMSNwu.rs) | [leetcode](https://leetcode-cn.com/problems/lMSNwu/) | Medium | +|1000262 | 重排链表 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/LGjMqU.rs) | [leetcode](https://leetcode-cn.com/problems/LGjMqU/) | Medium | +|1000263 | 回文链表 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/aMhZSa.rs) | [leetcode](https://leetcode-cn.com/problems/aMhZSa/) | Easy | +|1000270 | LRU 缓存 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/OrIXps.rs) | [leetcode](https://leetcode-cn.com/problems/OrIXps/) | Medium | +|1000273 | 有效的变位词 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/dKk3P7.rs) | [leetcode](https://leetcode-cn.com/problems/dKk3P7/) | Easy | +|1000275 | 变位词组 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/sfvd7V.rs) | [leetcode](https://leetcode-cn.com/problems/sfvd7V/) | Medium | +|1000276 | 外星语言是否排序 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/lwyVBB.rs) | [leetcode](https://leetcode-cn.com/problems/lwyVBB/) | Easy | +|1000278 | 最小时间差 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/569nqc.rs) | [leetcode](https://leetcode-cn.com/problems/569nqc/) | Medium | +|1000279 | 后缀表达式 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/8Zf90G.rs) | [leetcode](https://leetcode-cn.com/problems/8Zf90G/) | Medium | +|1000281 | 小行星碰撞 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/XagZNi.rs) | [leetcode](https://leetcode-cn.com/problems/XagZNi/) | Medium | +|1000282 | 每日温度 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/iIQa4I.rs) | [leetcode](https://leetcode-cn.com/problems/iIQa4I/) | Medium | +|1000286 | 三角形最小路径和 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/IlPe0q.rs) | [leetcode](https://leetcode-cn.com/problems/IlPe0q/) | Medium | +|1000288 | 加减的目标值 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/YaVDxD.rs) | [leetcode](https://leetcode-cn.com/problems/YaVDxD/) | Medium | +|1000292 | 滑动窗口的平均值 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/qIsx9U.rs) | [leetcode](https://leetcode-cn.com/problems/qIsx9U/) | Easy | +|1000295 | 往完全二叉树添加节点 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/NaqhDT.rs) | [leetcode](https://leetcode-cn.com/problems/NaqhDT/) | Medium | +|1000297 | 二叉树每层的最大值 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/hPov7L.rs) | [leetcode](https://leetcode-cn.com/problems/hPov7L/) | Medium | +|1000298 | 二叉树最底层最左边的值 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/LwUNpT.rs) | [leetcode](https://leetcode-cn.com/problems/LwUNpT/) | Medium | +|1000299 | 二叉树的右侧视图 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/WNC0Lk.rs) | [leetcode](https://leetcode-cn.com/problems/WNC0Lk/) | Medium | +|1000301 | 二叉树剪枝 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/pOCWxh.rs) | [leetcode](https://leetcode-cn.com/problems/pOCWxh/) | Medium | +|1000306 | 从根节点到叶节点的路径数字之和 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/3Etpl5.rs) | [leetcode](https://leetcode-cn.com/problems/3Etpl5/) | Medium | +|1000307 | 向下的路径节点之和 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/6eUYwP.rs) | [leetcode](https://leetcode-cn.com/problems/6eUYwP/) | Medium | +|1000311 | 展平二叉搜索树 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/NYBBNL.rs) | [leetcode](https://leetcode-cn.com/problems/NYBBNL/) | Easy | +|1000319 | 二叉搜索树中两个节点之和 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/opLdQZ.rs) | [leetcode](https://leetcode-cn.com/problems/opLdQZ/) | Easy | +|1000321 | 值和下标之差都在给定的范围内 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/7WqeDu.rs) | [leetcode](https://leetcode-cn.com/problems/7WqeDu/) | Medium | +|1000324 | 前 K 个高频元素 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/g5c51o.rs) | [leetcode](https://leetcode-cn.com/problems/g5c51o/) | Medium | +|1000333 | 山峰数组的顶部 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/B1IidL.rs) | [leetcode](https://leetcode-cn.com/problems/B1IidL/) | Easy | +|1000341 | 链表排序 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/7WHec2.rs) | [leetcode](https://leetcode-cn.com/problems/7WHec2/) | Medium | +|1000368 | 心算挑战 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/uOAnQW.rs) | [leetcode](https://leetcode-cn.com/problems/uOAnQW/) | Easy | +|1000433 | 宝石补给 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/WHnhjV.rs) | [leetcode](https://leetcode-cn.com/problems/WHnhjV/) | Easy | +|1000476 | 气温变化趋势 | [src](https://github.com/rustors/leetcode/blob/main/src/bin/6CE719.rs) | [leetcode](https://leetcode-cn.com/problems/6CE719/) | Easy | diff --git a/sort/Cargo.toml b/sort/Cargo.toml new file mode 100644 index 00000000..71a29e68 --- /dev/null +++ b/sort/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "sort" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/sort/src/bubble.rs b/sort/src/bubble.rs new file mode 100644 index 00000000..942e9029 --- /dev/null +++ b/sort/src/bubble.rs @@ -0,0 +1,19 @@ +/// 冒泡排序 +/// 从第一个元素开始挨个与后面的元素比较,前面大于后面则交换顺序,到最后一个元素一定是最大的那一个。 +/// 重复前一步 +/// 优化:如果一段连续到元素到列表末尾都没有交换过,说明此段连续元素都是有序的,因此不需要再次遍历比较这一段。 +pub fn sort(target: &mut [T]) { + let mut i = target.len(); + + while i > 0 { + let mut sort_index = i - 1; + for j in 0..i - 1 { + if target[j] > target[j + 1] { + sort_index = j + 1; + target.swap(j, j + 1); + } + } + + i = sort_index; + } +} diff --git a/sort/src/heap.rs b/sort/src/heap.rs new file mode 100644 index 00000000..f4913b50 --- /dev/null +++ b/sort/src/heap.rs @@ -0,0 +1,37 @@ +/// 构建一个大顶堆,然后去掉第一个元素再构建大顶堆 +pub fn sort(target: &mut [T]) { + if target.is_empty() { + return; + } + + for i in (0..(target.len() - 1) / 2).rev() { + heapfiy(target, i); + } + + let mut target = target; + + let len = target.len(); + for i in (0..len).rev() { + target.swap(0, i); // 堆定与最后一个元素交换 + + target = &mut target[0..i]; + heapfiy(target, 0); + } +} + +/// 从 n / 2 开始,因为后半部分一定是叶子结点。 +fn heapfiy(target: &mut [T], mut middle: usize) { + while middle * 2 + 1 < target.len() { + let mut max = middle * 2 + 1; + if middle * 2 + 2 < target.len() && target[max] < target[middle * 2 + 2] { + max = middle * 2 + 2; + } + + if target[middle] < target[max] { + target.swap(max, middle); + middle = max; + } else { + break; + } + } +} diff --git a/sort/src/insertion.rs b/sort/src/insertion.rs new file mode 100644 index 00000000..469d4846 --- /dev/null +++ b/sort/src/insertion.rs @@ -0,0 +1,13 @@ +/// 插入排序,遍历一个数,把它插入到前面合适的位置,其他的数往后移动 +pub fn sort(target: &mut [T]) { + for mut i in 1..target.len() { + for j in (0..i).rev() { + if target[j] > target[i] { + target.swap(i, j); + i = j; + } else { + break; + } + } + } +} diff --git a/sort/src/lib.rs b/sort/src/lib.rs new file mode 100644 index 00000000..407c3531 --- /dev/null +++ b/sort/src/lib.rs @@ -0,0 +1,50 @@ +pub mod bubble; +pub mod heap; +pub mod insertion; +pub mod merge; +pub mod quick; +pub mod selection; + +pub use bubble::sort as bubble_sort; +pub use heap::sort as heap_sort; +pub use insertion::sort as insertion_sort; +pub use merge::sort as merge_sort; +pub use quick::sort as quick_sort; +pub use selection::sort as selection_sort; + +#[cfg(test)] +mod tests { + macro_rules! test_case { + ($($func_name:ident),+) => { + $( + #[test] + fn $func_name() { + use super::$func_name as sort; + let s = "The Waker type allows for a loose coupling between the reactor-part and the executor-part of a runtime"; + let mut m: Vec = s.split(" ").map(|x| x.to_string()).collect(); + let mut m1 = m.clone(); + sort(&mut m1); + m.sort(); + + assert_eq!(m, m1); + + let mut m = vec![32,12,243,42,321,543,3213,21,33,5443,5,433]; + let mut m1 = m.clone(); + sort(&mut m1); + m.sort(); + + assert_eq!(m, m1); + } + )* + }; + } + + test_case! { + bubble_sort, + quick_sort, + selection_sort, + heap_sort, + insertion_sort, + merge_sort + } +} diff --git a/sort/src/merge.rs b/sort/src/merge.rs new file mode 100644 index 00000000..4b91e352 --- /dev/null +++ b/sort/src/merge.rs @@ -0,0 +1,49 @@ +/// 把序列分割成n个小块,然后再合并这n个小块 +pub fn sort(target: &mut [T]) { + merge(target); +} + +fn merge(target: &mut [T]) { + if target.is_empty() || target.len() == 1 { + return; + } + + if target.len() == 2 { + if target[0] > target[1] { + target.swap(0, 1); + } + return; + } + let len = target.len(); + + merge(&mut target[0..len >> 1]); + merge(&mut target[len >> 1..len]); + + // 合并两段, 使用双指针 + // p3 是 v的索引 + let (mut p1, mut p2, mut p3) = (0, len >> 1, 0); + + let v: Vec = target[0..len >> 1].into_iter().map(|x| x.clone()).collect(); + + while p1 < len { + if p2 < len && p3 < v.len() { + if target[p2] > v[p3] { + target[p1] = v[p3].clone(); + p3 += 1; + } else { + target[p1] = target[p2].clone(); + p2 += 1; + } + } else if p2 < len { + target[p1] = target[p2].clone(); + p2 += 1; + } else if p3 < v.len() { + target[p1] = v[p3].clone(); + p3 += 1; + } else { + return; + } + + p1 += 1; + } +} diff --git a/sort/src/quick.rs b/sort/src/quick.rs new file mode 100644 index 00000000..0ee0e711 --- /dev/null +++ b/sort/src/quick.rs @@ -0,0 +1,46 @@ +/// 原地排序的快速排序实现 +/// 步骤: +/// 1.指定一个基准值p(p为s[begin]), begin为0,end为len(s)-1 +/// 2.首先从后往前遍历,如果遍历的元素大于基准值,则继续往前遍历, end = end-1 +/// 3.如果从后往前遍历时的值小于基准值,begin的值赋值为s[end], begin = begin + 1 +/// 4.然后从前往后遍历,遍历值小于或者等于基准值时,继续向后遍历,begin = begin + 1 +/// 5.当遍历值大于或者等于基准值时,s[end] = s[begin] +/// 6.再次重复2-5步,直到begin == end为止 +/// 7.最后s[begin] = p +/// 8.递归快速排序以begin为分界线的两部分序列 +pub fn sort(target: &mut [T]) { + if target.len() < 2 { + return; + } + + let (p, mut begin, mut end) = (target[0].clone(), 0, target.len() - 1); + + while begin < end { + while begin < end { + match p.cmp(&target[end]) { + std::cmp::Ordering::Greater => { + target[begin] = target[end].clone(); + begin += 1; + break; + } + _ => end -= 1, + } + } + + while begin < end { + match p.cmp(&target[begin]) { + std::cmp::Ordering::Less => { + target[end] = target[begin].clone(); + end -= 1; + break; + } + _ => begin += 1, + } + } + } + + target[begin] = p; + + sort(&mut target[..begin]); + sort(&mut target[begin + 1..]); +} diff --git a/sort/src/selection.rs b/sort/src/selection.rs new file mode 100644 index 00000000..60dd94a4 --- /dev/null +++ b/sort/src/selection.rs @@ -0,0 +1,15 @@ +/// 从头开始遍历,遍历到最大的元素,与最后一个元素交换 +/// 然后又从头开始遍历,直到遍历完成为止 +pub fn sort(target: &mut [T]) { + for i in (0..target.len()).rev() { + let mut max = 0; + + for j in 0..=i { + if target[j] > target[max] { + max = j; + } + } + + target.swap(max, i); + } +} diff --git a/src/all.rs b/src/all.rs new file mode 100644 index 00000000..f45118da --- /dev/null +++ b/src/all.rs @@ -0,0 +1,39 @@ +use std::sync::{Arc, Mutex}; + +use crate::file; +use crate::http::Resp; + +/// 重新格式化 +pub async fn all() { + let files = file::get_all_bin_file().await; + + let v = Vec::::with_capacity(files.len()); + + let x = Arc::new(Mutex::new(v)); + let mut handlers = vec![]; + + for i in 0..=files.len() / 10 { + // 把files分块,分成10个文件一块 + let files = if i * 10 + 10 > files.len() { + files[i * 10..files.len()].to_vec() + } else { + files[i * 10..i * 10 + 10].to_vec() + }; + + let x = x.clone(); + + handlers.push(tokio::spawn(async move { + for i in files { + println!("{} downloading", i); + let resp = crate::http::get_question_info(&i).await; + x.lock().unwrap().push(resp); + } + })) + } + + for i in handlers { + i.await.unwrap(); + } + + file::write_readme(&mut *x.lock().unwrap()).await; +} diff --git a/src/bin/1nzheng-shu-zhong-1chu-xian-de-ci-shu-lcof.rs b/src/bin/1nzheng-shu-zhong-1chu-xian-de-ci-shu-lcof.rs new file mode 100644 index 00000000..a2825b47 --- /dev/null +++ b/src/bin/1nzheng-shu-zhong-1chu-xian-de-ci-shu-lcof.rs @@ -0,0 +1,30 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + /// https://leetcode.cn/problems/1nzheng-shu-zhong-1chu-xian-de-ci-shu-lcof/solution/mian-shi-ti-43-1n-zheng-shu-zhong-1-chu-xian-de-2/ + /// 找规律 + pub fn count_digit_one(n: i32) -> i32 { + let (mut n, mut r) = (n, 0); + let mut digit = 1; // 位数 + let mut low = 0; + while n > 0 { + let mut cur = n % 10; + let mut high = n / 10; + match cur { + 0 => r += (high * digit), + 1 => r += (high * digit + low + 1), + 2..=9 => r += ((high + 1) * digit), + _ => unreachable!(), + } + low += (cur * digit); + digit *= 10; + n = (n - cur) / 10; + } + + r + } +} diff --git a/src/bin/2-keys-keyboard.rs b/src/bin/2-keys-keyboard.rs new file mode 100644 index 00000000..0b28f797 --- /dev/null +++ b/src/bin/2-keys-keyboard.rs @@ -0,0 +1,39 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + assert_eq!(3, Solution::min_steps(3)); + assert_eq!(7, Solution::min_steps(10)); + assert_eq!(7, Solution::min_steps(7)); + assert_eq!(8, Solution::min_steps(18)); + assert_eq!(23, Solution::min_steps(23)); +} + +struct Solution; + +impl Solution { + pub fn min_steps(mut n: i32) -> i32 { + if n == 1 { + return 0; + } + + // 检查是否是质数 + let mut count = 0; + loop { + let mut flag = false; + for i in 2..n / 2 { + if n % i == 0 { + count += i; + n = n / i; + flag = true; + break; + } + } + if !flag { + count += n; + break; + } + } + + count + } +} diff --git a/src/bin/2VG8Kg.rs b/src/bin/2VG8Kg.rs new file mode 100644 index 00000000..389cae6a --- /dev/null +++ b/src/bin/2VG8Kg.rs @@ -0,0 +1,48 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() { + assert_eq!(Solution::min_sub_array_len(7, vec![2, 3, 1, 2, 4, 3]), 2); + assert_eq!(Solution::min_sub_array_len(4, vec![1, 4, 4]), 1); + assert_eq!( + Solution::min_sub_array_len(11, vec![1, 1, 1, 1, 1, 1, 1, 1]), + 0 + ); +} + +struct Solution; + +impl Solution { + /// 两个指针 start和end,start和end的和为sum + /// 如果sum >= target,则说明区间满足条件,start向前移动,sum减去start后移前下标位置的值 + /// 否则的话,end后移,sum加上当前end后移后当前下标的值 + pub fn min_sub_array_len(target: i32, nums: Vec) -> i32 { + let (mut start, mut end) = (0, 1); + let mut sum = nums[0]; + let mut ans = nums.len() + 1; + + loop { + if sum >= target { + ans = ans.min(end - start); + sum -= nums[start]; + start += 1; + } else { + end += 1; + if end > nums.len() { + break; + } + + sum += nums[end - 1]; + } + + if ans == 1 { + break; + } + } + + if ans == nums.len() + 1 { + 0 + } else { + ans as i32 + } + } +} diff --git a/src/bin/3Etpl5.rs b/src/bin/3Etpl5.rs new file mode 100644 index 00000000..a09ba051 --- /dev/null +++ b/src/bin/3Etpl5.rs @@ -0,0 +1,56 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +// Definition for a binary tree node. +#[derive(Debug, PartialEq, Eq)] +pub struct TreeNode { + pub val: i32, + pub left: Option>>, + pub right: Option>>, +} + +impl TreeNode { + #[inline] + pub fn new(val: i32) -> Self { + TreeNode { + val, + left: None, + right: None, + } + } +} +use std::cell::RefCell; +use std::rc::Rc; +impl Solution { + pub fn sum_numbers(root: Option>>) -> i32 { + let mut sum = 0; + Self::f(&mut sum, 0, root); + sum + } + + fn f(sum: &mut i32, val: i32, root: Option>>) { + if root.is_none() { + return; + } + + let v = root.clone().unwrap().borrow().val; + let left = root.clone().unwrap().borrow_mut().left.take(); + let right = root.clone().unwrap().borrow_mut().right.take(); + + if left.is_none() && right.is_none() { + *sum += v + val * 10; + return; + } + + if left.is_some() { + Self::f(sum, v + val * 10, left); + } + + if right.is_some() { + Self::f(sum, v + val * 10, right); + } + } +} diff --git a/src/bin/3sum-closest.rs b/src/bin/3sum-closest.rs new file mode 100644 index 00000000..ad6d4427 --- /dev/null +++ b/src/bin/3sum-closest.rs @@ -0,0 +1,65 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + /// 暴力破解法 + pub fn three_sum_closest1(nums: Vec, target: i32) -> i32 { + let mut sum: i32 = nums[0..3].iter().sum(); + + for i in 0..nums.len() { + for j in i + 1..nums.len() { + for k in j + 1..nums.len() { + let s = nums[i] + nums[j] + nums[k]; + if s == target { + return s; + } + sum = if (sum - target).abs() > (s - target).abs() { + s + } else { + sum + }; + } + } + } + + sum + } + + /// 排序后,和是递增的 + pub fn three_sum_closest(nums: Vec, target: i32) -> i32 { + let mut nums = nums; + nums.sort(); + let mut sum: i32 = nums[..3].iter().sum(); + + // 因为排序后递增,所以前三个数的和是最小的,当前三个数的和都大于target时,其他数的和肯定大于target + if sum > target { + return sum; + } + + for i in 0..nums.len() { + let (mut left, mut right) = (i + 1, nums.len() - 1); + + while left < right { + let s = nums[i] + nums[left] + nums[right]; + if s == target { + return s; + } else if s > target { + right -= 1; + } else { + left += 1; + } + + sum = if (s - target).abs() > (sum - target).abs() { + sum + } else { + s + }; + } + } + + sum + } +} diff --git a/src/bin/3sum.rs b/src/bin/3sum.rs new file mode 100644 index 00000000..f44cf40a --- /dev/null +++ b/src/bin/3sum.rs @@ -0,0 +1,60 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + // println!("{:?}", Solution::three_sum(vec![0, 0, 0, 0])); + // println!("{:?}", Solution::three_sum(vec![-1, 0, 1, 2, -1, -4])); + // println!("{:?}", Solution::three_sum(vec![1, -1, -1, 0])); + println!("{:?}", Solution::three_sum(vec![-2, 0, 0, 2, 2])); +} + +struct Solution; + +impl Solution { + /// 先排序 + /// 然后在从头开始找 + pub fn three_sum(nums: Vec) -> Vec> { + let mut result = vec![]; + + if nums.len() < 3 { + return result; + } + + let mut nums = nums; + nums.sort(); + + for i in 0..nums.len() { + if nums[i] > 0 { + break; + } + + // 当前后两个数相同时,第一个数已经把这个数的情况给计算在内了,所以直接跳转到下一个数字 + if i > 0 && nums[i] == nums[i - 1] { + continue; + } + + let (mut left, mut right) = (i + 1, nums.len() - 1); + + while left < right { + match 0.cmp(&(nums[i] + nums[left] + nums[right])) { + std::cmp::Ordering::Equal => { + result.push(vec![nums[i], nums[left], nums[right]]); + left += 1; + right -= 1; + + while left < right && nums[left] == nums[left - 1] { + left += 1; + } + + while left < right && nums[right] == nums[right + 1] { + right -= 1; + } + } + std::cmp::Ordering::Less => right -= 1, + std::cmp::Ordering::Greater => left += 1, + } + } + } + + result + } +} diff --git a/src/bin/4sum.rs b/src/bin/4sum.rs new file mode 100644 index 00000000..81e07565 --- /dev/null +++ b/src/bin/4sum.rs @@ -0,0 +1,87 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + println!("{:?}", Solution::four_sum(vec![1, 0, -1, 0, -2, 2], 0)); + println!("{:?}", Solution::four_sum(vec![0, 0, 0, 0], 0)); + println!("{:?}", Solution::four_sum(vec![-2, -1, -1, 1, 1, 2, 2], 0)); + println!( + "{:?}", + Solution::four_sum(vec![1, -2, -5, -4, -3, 3, 3, 5], -11) + ); +} + +struct Solution; + +impl Solution { + /// 第一个数加后面三个数集合 + pub fn four_sum(nums: Vec, target: i32) -> Vec> { + let mut result = vec![]; + if nums.len() < 4 { + return result; + } + + let mut nums = nums; + nums.sort(); + + for i in 0..nums.len() { + if nums[i] > 0 && nums[i] > target { + break; + } + + if i > 0 && nums[i] == nums[i - 1] { + continue; + } + + let r = Self::three_sum(&nums[i + 1..], target - nums[i]); + + for mut v in r.into_iter() { + v[0] = nums[i]; + result.push(v); + } + } + + result + } + + fn three_sum(nums: &[i32], target: i32) -> Vec> { + let mut r = vec![]; + if nums.len() < 3 { + return r; + } + + for i in 0..nums.len() { + if nums[i] > 0 && nums[i] > target { + break; + } + + if i > 0 && nums[i] == nums[i - 1] { + continue; + } + + let (mut left, mut right) = (i + 1, nums.len() - 1); + + while left < right { + let s = nums[i] + nums[left] + nums[right]; + if s == target { + r.push(vec![0, nums[i], nums[left], nums[right]]); + left += 1; + right -= 1; + + while left < right && nums[left] == nums[left - 1] { + left += 1; + } + + while left < right && nums[right] == nums[right + 1] { + right -= 1; + } + } else if s < target { + left += 1; + } else { + right -= 1; + } + } + } + + r + } +} diff --git a/src/bin/569nqc.rs b/src/bin/569nqc.rs new file mode 100644 index 00000000..dba91787 --- /dev/null +++ b/src/bin/569nqc.rs @@ -0,0 +1,43 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +use core::time; + +fn main() {} + +struct Solution; + +impl Solution { + pub fn find_min_difference(time_points: Vec) -> i32 { + // 因为只有1440种可能,因此大于这个值的话必定有2个相同的,直接返回0即可 + // 鸽巢原理/抽屉原理 + if time_points.len() > 1440 { + return 0; + } + + let mut time_points = time_points; + time_points.sort(); + + let (h1, m1) = time_points[time_points.len() - 1].split_once(':').unwrap(); + let (h2, m2) = time_points[0].split_once(':').unwrap(); + + let mut t = h2.trim_start_matches('0').parse::().unwrap_or(0) * 60 + + m2.parse::().unwrap_or(0) + + (23 - h1.trim_start_matches('0').parse::().unwrap_or(0)) * 60 + + (60 - m1.trim_start_matches('0').parse::().unwrap_or(0)); + + for i in 1..time_points.len() { + let (h1, m1) = time_points[i - 1].split_once(':').unwrap(); + let (h2, m2) = time_points[i].split_once(':').unwrap(); + + t = t.min( + (h2.trim_start_matches('0').parse::().unwrap_or(0) + - h1.trim_start_matches('0').parse::().unwrap_or(0)) + * 60 + + m2.trim_start_matches('0').parse::().unwrap_or(0) + - m1.trim_start_matches('0').parse::().unwrap_or(0), + ); + } + + t + } +} diff --git a/src/bin/6CE719.rs b/src/bin/6CE719.rs new file mode 100644 index 00000000..82508619 --- /dev/null +++ b/src/bin/6CE719.rs @@ -0,0 +1,26 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn temperature_trend(temperature_a: Vec, temperature_b: Vec) -> i32 { + let mut result = 0; + let mut current = 0; + + for i in 1..temperature_a.len() { + if temperature_a[i - 1].cmp(&temperature_a[i]) + == temperature_b[i - 1].cmp(&temperature_b[i]) + { + current += 1; + } else { + current = 0; + } + + result = result.max(current); + } + + result + } +} diff --git a/src/bin/6eUYwP.rs b/src/bin/6eUYwP.rs new file mode 100644 index 00000000..8fbc6690 --- /dev/null +++ b/src/bin/6eUYwP.rs @@ -0,0 +1,56 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +// Definition for a binary tree node. +#[derive(Debug, PartialEq, Eq)] +pub struct TreeNode { + pub val: i32, + pub left: Option>>, + pub right: Option>>, +} + +impl TreeNode { + #[inline] + pub fn new(val: i32) -> Self { + TreeNode { + val, + left: None, + right: None, + } + } +} +use std::cell::RefCell; +use std::rc::Rc; +impl Solution { + pub fn path_sum(root: Option>>, target_sum: i32) -> i32 { + let mut ans = 0; + ans += Self::travel(root.clone(), target_sum as i64); + if root.is_some() { + ans += Self::path_sum(root.clone().unwrap().borrow().left.clone(), target_sum); + ans += Self::path_sum(root.clone().unwrap().borrow().right.clone(), target_sum); + } + + ans + } + + pub fn travel(root: Option>>, target_sum: i64) -> i32 { + if root.is_none() { + return 0; + } + + let mut ans = 0; + let root = root.unwrap(); + let val = root.borrow().val as i64; + if target_sum == val { + ans += 1; + } + + let left = root.borrow().left.clone(); + let right = root.borrow().right.clone(); + + ans + Self::travel(left, target_sum - val) + Self::travel(right, target_sum - val) + } +} diff --git a/src/bin/7WHec2.rs b/src/bin/7WHec2.rs new file mode 100644 index 00000000..9f721a6c --- /dev/null +++ b/src/bin/7WHec2.rs @@ -0,0 +1,77 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +// Definition for singly-linked list. +#[derive(PartialEq, Eq, Clone, Debug)] +pub struct ListNode { + pub val: i32, + pub next: Option>, +} + +impl ListNode { + #[inline] + fn new(val: i32) -> Self { + ListNode { next: None, val } + } +} +impl Solution { + /// 归并排序 + pub fn sort_list(mut head: Option>) -> Option> { + let mut length = 0; + let mut ptr = head.as_ref(); + + while ptr.is_some() { + length += 1; + ptr = ptr.and_then(|x| x.next.as_ref()); + } + + Self::sort(head, length) + } + + pub fn sort(mut head: Option>, length: i32) -> Option> { + if head.is_none() || head.as_ref().unwrap().next.is_none() { + return head; + } + + let mut middle = head.as_mut(); + + for _j in 0..length / 2 - 1 { + middle = middle.and_then(|x| x.next.as_mut()); + } + + let right = middle.and_then(|x| x.next.take()); + + let mut right = Self::sort(right, length - (length / 2)); + let mut left = Self::sort(head, length / 2); + + let mut ans = Some(Box::new(ListNode::new(-1))); + let mut current = &mut ans.as_mut().unwrap().next; + + while left.is_some() || right.is_some() { + if left.is_none() { + current.insert(right.unwrap()); + break; + } else if right.is_none() { + current.insert(left.unwrap()); + break; + } else { + if left.as_ref().unwrap().val < right.as_ref().unwrap().val { + let new_left = left.as_mut().unwrap().next.take(); + current.insert(left.unwrap()); + left = new_left; + } else { + let new_right = right.as_mut().unwrap().next.take(); + current.insert(right.unwrap()); + right = new_right; + } + + current = &mut current.as_mut().unwrap().next; + } + } + + ans.and_then(|mut x| x.next.take()) + } +} diff --git a/src/bin/7WqeDu.rs b/src/bin/7WqeDu.rs new file mode 100644 index 00000000..d3bba7c2 --- /dev/null +++ b/src/bin/7WqeDu.rs @@ -0,0 +1,25 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn contains_nearby_almost_duplicate(nums: Vec, k: i32, t: i32) -> bool { + for i in 0..nums.len() { + for j in 0..nums.len() { + if i == j { + continue; + } + + if (nums[i] as i64 - nums[j] as i64).abs() <= t as i64 + && (i as i32 - j as i32).abs() <= k + { + return true; + } + } + } + + false + } +} diff --git a/src/bin/8Zf90G.rs b/src/bin/8Zf90G.rs new file mode 100644 index 00000000..0d893b9f --- /dev/null +++ b/src/bin/8Zf90G.rs @@ -0,0 +1,41 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + /// 逆波兰表达式配合栈 + pub fn eval_rpn(tokens: Vec) -> i32 { + let mut stack = vec![]; + for i in tokens { + match &*i { + "+" => { + let x = stack.pop().unwrap(); + let y = stack.pop().unwrap(); + stack.push(x + y); + } + "-" => { + let x = stack.pop().unwrap(); + let y = stack.pop().unwrap(); + stack.push(y - x); + } + "*" => { + let x = stack.pop().unwrap(); + let y = stack.pop().unwrap(); + stack.push(x * y); + } + "/" => { + let x = stack.pop().unwrap(); + let y = stack.pop().unwrap(); + stack.push(y / x); + } + s => { + stack.push(s.parse().unwrap()); + } + } + } + + stack.pop().unwrap() + } +} diff --git a/src/bin/A1NYOS.rs b/src/bin/A1NYOS.rs new file mode 100644 index 00000000..f8ad56cd --- /dev/null +++ b/src/bin/A1NYOS.rs @@ -0,0 +1,43 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() { + assert_eq!(Solution::find_max_length(vec![0, 1]), 2); + assert_eq!(Solution::find_max_length(vec![0, 1, 0]), 2); + assert_eq!(Solution::find_max_length(vec![0, 0, 1, 0, 0, 0, 1, 1]), 6); +} + +struct Solution; + +impl Solution { + /// count记录0的数量-1的数量 + /// 当counter为0时,则说明此时满足条件 + /// 当counter不为0时,找到相同counter时的子数组,则减去相同counter的子数组剩余的数组就是0和1相同数量的子数组 + pub fn find_max_length(nums: Vec) -> i32 { + let mut nums = nums; + let mut count = 0; // 0的数量-1的数量 + + let mut ans = 0; + let mut map = std::collections::HashMap::new(); + + for i in 0..nums.len() { + if nums[i] == 0 { + count += 1; + } else { + count -= 1; + } + + if count == 0 { + ans = ans.max(i as i32 + 1); + } else { + match map.get(&count) { + Some(&x) => ans = ans.max(i as i32 - x), + None => {} + } + + map.entry(count).or_insert(i as i32); + } + } + + ans + } +} diff --git a/src/bin/B1IidL.rs b/src/bin/B1IidL.rs new file mode 100644 index 00000000..9b91cb10 --- /dev/null +++ b/src/bin/B1IidL.rs @@ -0,0 +1,24 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn peak_index_in_mountain_array(arr: Vec) -> i32 { + let (mut start, mut end) = (0, arr.len() - 1); + + while start < end { + let mut middle = (start + end) / 2; + if arr[middle] > arr[middle - 1] && arr[middle] > arr[middle + 1] { + return middle as i32; + } else if arr[middle] > arr[middle - 1] && arr[middle] < arr[middle + 1] { + start = middle + 1; + } else { + end = middle; + } + } + + unreachable!() + } +} diff --git a/src/bin/IDBivT.rs b/src/bin/IDBivT.rs new file mode 100644 index 00000000..69b47e7d --- /dev/null +++ b/src/bin/IDBivT.rs @@ -0,0 +1,28 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn generate_parenthesis(n: i32) -> Vec { + if n == 1 { + return vec!["()".to_string()]; + } else if n == 0 { + return vec!["".to_string()]; + } + let mut ans = vec![]; + for i in 0..n { + let mut mid = vec![]; + for sub_string1 in Self::generate_parenthesis(i) { + mid.push(format!("({sub_string1})")); + } + for m in mid { + for sub_string2 in Self::generate_parenthesis(n - 1 - i) { + ans.push(format!("{m}{sub_string2}")); + } + } + } + ans + } +} diff --git a/src/bin/IlPe0q.rs b/src/bin/IlPe0q.rs new file mode 100644 index 00000000..1363cfd5 --- /dev/null +++ b/src/bin/IlPe0q.rs @@ -0,0 +1,29 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn minimum_total(triangle: Vec>) -> i32 { + let mut triangle = triangle; + + for i in 1..triangle.len() { + for j in 0..triangle[i].len() { + if j == 0 { + triangle[i][j] += triangle[i - 1][0]; + } else if j == triangle[i].len() - 1 { + triangle[i][j] += triangle[i - 1][j - 1]; + } else { + triangle[i][j] += triangle[i - 1][j - 1].min(triangle[i - 1][j]); + } + } + } + + triangle[triangle.len() - 1] + .iter() + .map(|x| *x) + .min() + .unwrap() + } +} diff --git a/src/bin/JFETK5.rs b/src/bin/JFETK5.rs new file mode 100644 index 00000000..51b3508a --- /dev/null +++ b/src/bin/JFETK5.rs @@ -0,0 +1,99 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() { + println!("{}", Solution::add_binary("11".into(), "10".into())); + println!("{}", Solution::add_binary("1010".into(), "1011".into())); +} + +struct Solution; + +impl Solution { + pub fn add_binary(a: String, b: String) -> String { + let mut ans = vec![0; a.len().max(b.len()) + 1]; + let l = ans.len(); + let mut sign = b'0'; // 符号位 + let (a, b) = (a.as_bytes(), b.as_bytes()); + + let mut i = 1; + + while i <= a.len() || i <= b.len() { + if i <= a.len() && i <= b.len() { + match (a[a.len() - i], b[b.len() - i], sign) { + (b'0', b'0', s) => { + ans[l - i] = s; + sign = b'0'; + } + (b'1', b'0', s) => { + if s == b'1' { + ans[l - i] = b'0'; + sign = b'1'; + } else { + ans[l - i] = b'1'; + sign = b'0'; + } + } + (b'0', b'1', s) => { + if s == b'1' { + ans[l - i] = b'0'; + sign = b'1'; + } else { + ans[l - i] = b'1'; + sign = b'0'; + } + } + (b'1', b'1', s) => { + ans[l - i] = s; + sign = b'1'; + } + _ => unreachable!(), + } + } else if i <= a.len() { + match (a[a.len() - i], sign) { + (b'0', s) => { + ans[l - i] = s; + sign = b'0'; + } + (b'1', s) => { + if s == b'0' { + ans[l - i] = b'1'; + sign = b'0'; + } else { + ans[l - i] = b'0'; + sign = b'1'; + } + } + _ => unreachable!(), + } + } else { + match (b[b.len() - i], sign) { + (b'0', s) => { + ans[l - i] = s; + sign = b'0'; + } + (b'1', s) => { + if s == b'0' { + ans[l - i] = b'1'; + sign = b'0'; + } else { + ans[l - i] = b'0'; + sign = b'1'; + } + } + _ => unreachable!(), + } + } + + i += 1; + } + + if sign == b'1' { + ans[l - i] = b'1'; + } + + if ans[0] == b'1' { + String::from_utf8_lossy(&ans).to_string() + } else { + String::from_utf8_lossy(&ans[1..]).to_string() + } + } +} diff --git a/src/bin/Ju9Xwi.rs b/src/bin/Ju9Xwi.rs new file mode 100644 index 00000000..f2d5e403 --- /dev/null +++ b/src/bin/Ju9Xwi.rs @@ -0,0 +1,25 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn least_minutes(n: i32) -> i32 { + if n <= 1 { + return 1; + } + + let mut x = 1; + let mut r = 0; + for i in 1.. { + x *= 2; + r = i as i32; + if x >= n { + break; + } + } + + r + 1 + } +} diff --git a/src/bin/LGjMqU.rs b/src/bin/LGjMqU.rs new file mode 100644 index 00000000..f5e5cb1a --- /dev/null +++ b/src/bin/LGjMqU.rs @@ -0,0 +1,96 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +use std::vec; + +fn main() {} + +struct Solution; + +// Definition for singly-linked list. +#[derive(PartialEq, Eq, Clone, Debug)] +pub struct ListNode { + pub val: i32, + pub next: Option>, +} + +impl ListNode { + #[inline] + fn new(val: i32) -> Self { + ListNode { next: None, val } + } +} +impl Solution { + /// 1.双指针找到链表的中心 + /// 2.然后翻转后半部分的链表 + /// 3.合并前后部分 + pub fn reorder_list(head: &mut Option>) { + // 注意:找到后半部分可以使用快慢指针,但是rust我不会 + let mut len = 0; + let mut current = head.as_deref(); + while current.is_some() { + len += 1; + current = current.unwrap().next.as_deref(); + } + let mut middle = head.as_deref_mut(); + for i in 0..len / 2 { + middle = middle.unwrap().next.as_deref_mut(); + } + + if middle.is_none() { + return; + } + + let mut middle = middle.unwrap().next.take(); + // 翻转middle + let mut dummy = Box::new(ListNode::new(-1)); + while middle.is_some() { + let n = dummy.next.take(); + let c = middle.as_deref_mut().unwrap().next.take(); + + dummy.next = middle; + dummy.next.as_deref_mut().unwrap().next = n; + + middle = c; + } + + let (mut l1, mut l2) = (head.as_deref_mut().unwrap().next.take(), dummy.next.take()); + + let mut dummy = Box::new(ListNode::new(-1)); + let mut current = &mut dummy.next; + + loop { + match (l1, l2) { + (Some(mut x1), Some(mut x2)) => { + l1 = x1.next.take(); + l2 = x2.next.take(); + + current.insert(x2); + current = &mut current.as_deref_mut().unwrap().next; + + current.insert(x1); + current = &mut current.as_deref_mut().unwrap().next; + } + + (Some(mut x1), None) => { + l1 = x1.next.take(); + l2 = None; + + current.insert(x1); + current = &mut current.as_deref_mut().unwrap().next; + } + + (None, Some(mut x2)) => { + l1 = None; + l2 = x2.next.take(); + + current.insert(x2); + current = &mut current.as_deref_mut().unwrap().next; + } + + _ => break, + } + } + + head.as_deref_mut().unwrap().next = dummy.next.take(); + } +} diff --git a/src/bin/LwUNpT.rs b/src/bin/LwUNpT.rs new file mode 100644 index 00000000..e2a66bed --- /dev/null +++ b/src/bin/LwUNpT.rs @@ -0,0 +1,60 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +// Definition for a binary tree node. +#[derive(Debug, PartialEq, Eq)] +pub struct TreeNode { + pub val: i32, + pub left: Option>>, + pub right: Option>>, +} + +impl TreeNode { + #[inline] + pub fn new(val: i32) -> Self { + TreeNode { + val, + left: None, + right: None, + } + } +} + +use std::cell::RefCell; +use std::rc::Rc; +use std::vec; + +impl Solution { + pub fn find_bottom_left_value(root: Option>>) -> i32 { + let mut stack = vec![root]; + + let mut ans = 0; + + while !stack.is_empty() { + let mut new_stack = vec![]; + + for i in 0..stack.len() { + if i == 0 { + ans = stack[i].clone().as_deref().unwrap().borrow().val; + } + + let node = stack[i].clone().unwrap(); + + if node.borrow().left.is_some() { + new_stack.push(node.borrow_mut().left.take()); + } + + if node.borrow().right.is_some() { + new_stack.push(node.borrow_mut().right.take()); + } + } + + stack = new_stack; + } + + ans + } +} diff --git a/src/bin/MPnaiL.rs b/src/bin/MPnaiL.rs new file mode 100644 index 00000000..63b56a5f --- /dev/null +++ b/src/bin/MPnaiL.rs @@ -0,0 +1,67 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() { + assert!(Solution::check_inclusion("ab".into(), "eidbaooo".into())); +} + +struct Solution; + +impl Solution { + pub fn check_inclusion(s1: String, s2: String) -> bool { + if s1.len() > s2.len() { + return false; + } + + let mut cnt = [0; 26]; + + for i in 0..s1.len() { + cnt[(s1.as_bytes()[i] - b'a') as usize] -= 1; + cnt[(s2.as_bytes()[i] - b'a') as usize] += 1; + } + + let mut diff = 0; // 统计不同字符的个数 + + for &i in cnt.iter() { + if i != 0 { + diff += 1; + } + } + + if diff == 0 { + return true; + } + + for i in s1.len()..s2.len() { + let (a, b) = (s2.as_bytes()[i - s1.len()], s2.as_bytes()[i]); + if a == b { + continue; + } + + if cnt[(a - b'a') as usize] == 0 { + diff += 1; + } + + cnt[(a - b'a') as usize] -= 1; + + if cnt[(a - b'a') as usize] == 0 { + diff -= 1; + } + + if cnt[(b - b'a') as usize] == 0 { + diff += 1; + } + + cnt[(b - b'a') as usize] += 1; + + if cnt[(b - b'a') as usize] == 0 { + diff -= 1; + } + + if diff == 0 { + return true; + } + } + + false + } +} diff --git a/src/bin/NYBBNL.rs b/src/bin/NYBBNL.rs new file mode 100644 index 00000000..70327e8b --- /dev/null +++ b/src/bin/NYBBNL.rs @@ -0,0 +1,67 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +// Definition for a binary tree node. +#[derive(Debug, PartialEq, Eq)] +pub struct TreeNode { + pub val: i32, + pub left: Option>>, + pub right: Option>>, +} + +impl TreeNode { + #[inline] + pub fn new(val: i32) -> Self { + TreeNode { + val, + left: None, + right: None, + } + } +} + +use std::cell::RefCell; +use std::rc::Rc; +impl Solution { + pub fn increasing_bst(root: Option>>) -> Option>> { + if root.is_none() { + return None; + } + + let (ans, _) = Self::f(root); + ans + } + + // 返回头部和尾部 + fn f( + root: Option>>, + ) -> (Option>>, Option>>) { + let root = root.unwrap(); + let left = root.borrow_mut().left.take(); + let right = root.borrow_mut().right.take(); + + match (left, right) { + (Some(l), Some(r)) => { + let (n1, m1) = Self::f(Some(l)); + let (n2, m2) = Self::f(Some(r)); + m1.clone().unwrap().borrow_mut().right = Some(root.clone()); + root.borrow_mut().right = n2; + (n1, m2) + } + (Some(l), None) => { + let (n, m) = Self::f(Some(l)); + m.clone().unwrap().borrow_mut().right = Some(root.clone()); + (n, Some(root.clone())) + } + (None, Some(r)) => { + let (n, m) = Self::f(Some(r)); + root.borrow_mut().right = n; + (Some(root), m) + } + (None, None) => (Some(root.clone()), Some(root.clone())), + } + } +} diff --git a/src/bin/NaqhDT.rs b/src/bin/NaqhDT.rs new file mode 100644 index 00000000..2d576547 --- /dev/null +++ b/src/bin/NaqhDT.rs @@ -0,0 +1,99 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +use std::{cell::RefCell, rc::Rc}; + +fn main() {} + +struct Solution; + +// Definition for a binary tree node. +#[derive(Debug, PartialEq, Eq)] +pub struct TreeNode { + pub val: i32, + pub left: Option>>, + pub right: Option>>, +} + +impl TreeNode { + #[inline] + pub fn new(val: i32) -> Self { + TreeNode { + val, + left: None, + right: None, + } + } +} +struct CBTInserter { + count: i32, + root: Option>>, +} + +/** + * `&self` means the method takes an immutable reference. + * If you need a mutable reference, change it to `&mut self` instead. + */ +impl CBTInserter { + fn new(root: Option>>) -> Self { + let mut count = 0; + let mut stack = vec![]; + if root.is_some() { + stack.push(root.clone().unwrap()); + } + while !stack.is_empty() { + let mut new_stack = vec![]; + while let Some(s) = stack.pop() { + if s.borrow().left.is_some() { + new_stack.push(s.borrow().left.clone().unwrap()); + } + + if s.borrow().right.is_some() { + new_stack.push(s.borrow().right.clone().unwrap()); + } + count += 1; + } + + stack = new_stack; + } + + Self { root, count } + } + + fn insert(&mut self, v: i32) -> i32 { + self.count += 1; + + let mut node = self.root.clone(); + + for i in (1..=self.get_bits_len() - 2).rev() { + if self.count >> i & 1 == 0 { + node = node.map(|x| x.borrow().left.clone().unwrap()); + } else { + node = node.map(|x| x.borrow().right.clone().unwrap()); + } + } + let ans = node.as_deref().unwrap().borrow().val; + + if self.count & 1 == 0 { + node.unwrap().borrow_mut().left = Some(Rc::new(RefCell::new(TreeNode::new(v)))); + } else { + node.unwrap().borrow_mut().right = Some(Rc::new(RefCell::new(TreeNode::new(v)))); + } + + ans + } + + fn get_root(&self) -> Option>> { + self.root.clone() + } + + fn get_bits_len(&self) -> i32 { + let mut ans = 0; + let mut c = self.count; + while c > 0 { + ans += 1; + c >>= 1; + } + + ans + } +} diff --git a/src/bin/O4NDxx.rs b/src/bin/O4NDxx.rs new file mode 100644 index 00000000..ad8ea35e --- /dev/null +++ b/src/bin/O4NDxx.rs @@ -0,0 +1,82 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() { + let n = NumMatrix::new(vec![ + vec![3, 0, 1, 4, 2], + vec![5, 6, 3, 2, 1], + vec![1, 2, 0, 1, 5], + vec![4, 1, 0, 1, 7], + vec![1, 0, 3, 0, 5], + ]); + + assert_eq!(n.sum_region(2, 1, 4, 3), 8); +} + +struct Solution; + +struct NumMatrix { + matrix: Vec>, +} + +/** + * `&self` means the method takes an immutable reference. + * If you need a mutable reference, change it to `&mut self` instead. + */ +impl NumMatrix { + ///[ + /// [3,0,1,4,2], + /// [5,6,3,2,1], + /// [1,2,0,1,5], + /// [4,1,0,1,7], + /// [1,0,3,0,5] + /// ] + /// + /// [ + /// [3,3,4,8,10], + /// [5,11,14,16,17], + /// [1,3,3,4,9], + /// [4,5,5,6,13], + /// [1,1,4,4,9] + /// ] + /// + /// [ + /// [0,0,0,0,0,0], + /// [0,3,3,4,8,10], + /// [0,8,14,18,24,27], + /// [0,9,17,21,28,36], + /// [0,13,22,26,34,49], + /// [0,14,23,30,38,58] + /// ] + /// + /// sum = sum[row2 + 1][col2 + 1] - sum[row1][col2 + 1] - sum[row2 + 1][col1] + sum[row1][col1] + fn new(matrix: Vec>) -> Self { + let mut matrix = matrix; + + for i in 0..matrix.len() { + for j in 1..matrix[0].len() { + matrix[i][j] += matrix[i][j - 1]; + } + } + + let mut m = vec![vec![0; matrix[0].len() + 1]; matrix.len() + 1]; + + for i in 0..matrix.len() { + for j in 0..matrix[0].len() { + if i != 0 { + matrix[i][j] += matrix[i - 1][j]; + } + + m[i + 1][j + 1] = matrix[i][j]; + } + } + + Self { matrix: m } + } + + fn sum_region(&self, row1: i32, col1: i32, row2: i32, col2: i32) -> i32 { + self.matrix[row2 as usize + 1][col2 as usize + 1] + - self.matrix[row1 as usize][col2 as usize + 1] + - self.matrix[row2 as usize + 1][col1 as usize] + + self.matrix[row1 as usize][col1 as usize] + } +} diff --git a/src/bin/OrIXps.rs b/src/bin/OrIXps.rs new file mode 100644 index 00000000..ae2a4985 --- /dev/null +++ b/src/bin/OrIXps.rs @@ -0,0 +1,134 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() { + let mut lru = LRUCache::new(2); + lru.put(1, 1); + // println!("{:?}", lru.list); + + lru.put(2, 2); + // println!("{:?}", lru.list); + assert_eq!(lru.get(1), 1); + // println!("{:?}", lru.list); + lru.put(3, 3); + assert_eq!(lru.get(2), -1); + lru.put(4, 4); + assert_eq!(lru.get(1), -1); + assert_eq!(lru.get(3), 3); + assert_eq!(lru.get(4), 4); +} + +struct Solution; + +#[derive(Debug)] +struct LinkedList { + head: Option>>, + tail: Option>>, +} + +impl LinkedList { + fn new() -> Self { + Self { + head: None, + tail: None, + } + } + + fn take(&mut self, node: std::rc::Rc>) { + let pre = node.borrow_mut().pre.take(); + let next = node.borrow_mut().next.take(); + + pre.clone().map(|x| x.borrow_mut().next = next.clone()); + next.clone().map(|x| x.borrow_mut().pre = pre.clone()); + + if next.is_none() { + self.tail = pre.clone(); + } + + if pre.is_none() { + self.head = next.clone(); + } + } + + fn push(&mut self, node: std::rc::Rc>) { + let head = self.head.take(); + node.borrow_mut().next = head.clone(); + + head.map(|x| x.borrow_mut().pre = Some(node.clone())); + self.head = Some(node.clone()); + + if self.tail.is_none() { + self.tail = self.head.clone(); + } + } +} + +#[derive(Debug)] +struct Node { + key: i32, + val: i32, + pre: Option>>, + next: Option>>, +} + +struct LRUCache { + capacity: usize, + map: std::collections::HashMap>>, + list: LinkedList, +} + +/** + * `&self` means the method takes an immutable reference. + * If you need a mutable reference, change it to `&mut self` instead. + */ + +/** + * Your LRUCache object will be instantiated and called as such: + * let obj = LRUCache::new(capacity); + * let ret_1: i32 = obj.get(key); + * obj.put(key, value); + */ + +impl LRUCache { + fn new(capacity: i32) -> Self { + Self { + capacity: capacity as usize, + map: std::collections::HashMap::new(), + list: LinkedList::new(), + } + } + + fn get(&mut self, key: i32) -> i32 { + if let Some(x) = self.map.get(&key) { + self.list.take(x.clone()); + self.list.push(x.clone()); + x.borrow().val + } else { + -1 + } + } + + fn put(&mut self, key: i32, value: i32) { + if let Some(x) = self.map.get(&key) { + self.list.take(x.clone()); + self.list.push(x.clone()); + x.borrow_mut().val = value; + } else { + // remove a value + if self.map.len() == self.capacity { + let tail = self.list.tail.clone().unwrap(); + self.list.take(tail.clone()); + self.map.remove(&tail.borrow().key); + } + + let node = std::rc::Rc::new(std::cell::RefCell::new(Node { + key, + val: value, + pre: None, + next: None, + })); + + self.list.push(node.clone()); + self.map.insert(key, node); + } + } +} diff --git a/src/bin/QTMn0o.rs b/src/bin/QTMn0o.rs new file mode 100644 index 00000000..8bc38f2d --- /dev/null +++ b/src/bin/QTMn0o.rs @@ -0,0 +1,33 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() { + assert_eq!(Solution::subarray_sum(vec![1, 1, 1], 2), 2); + assert_eq!(Solution::subarray_sum(vec![1, 2, 3], 3), 2); +} + +struct Solution; + +impl Solution { + /// 先求出前缀和 + /// 然后遍历前缀和列表,如果当前值为k,则说明此位置的前缀和满足条件 + /// 然后再判断是否有当前值-k存在,获取存在的数量 + pub fn subarray_sum(mut nums: Vec, k: i32) -> i32 { + for i in 1..nums.len() { + let (x, y) = (nums[i], nums[i - 1]); + nums[i] = x + y; + } + + let mut map = std::collections::HashMap::new(); + let mut ans = 0; + for i in nums { + if i == k { + ans += 1; + } + + ans += *map.get(&(i - k)).unwrap_or(&0); + map.entry(i).and_modify(|x| *x += 1).or_insert(1); + } + + ans + } +} diff --git a/src/bin/RQku0D.rs b/src/bin/RQku0D.rs new file mode 100644 index 00000000..ee64fe0d --- /dev/null +++ b/src/bin/RQku0D.rs @@ -0,0 +1,40 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() { + assert!(Solution::valid_palindrome("aba".into())); + assert!(Solution::valid_palindrome("abca".into())); + assert!(!Solution::valid_palindrome("abc".into())); + assert!(Solution::valid_palindrome("cbbcc".into())); + assert!(Solution::valid_palindrome("aguokepatgbnvfqmgmlcupuufxoohdfpgjdmysgvhmvffcnqxjjxqncffvmhvgsymdjgpfdhooxfuupuculmgmqfvnbgtapekouga".into())); +} + +struct Solution; + +impl Solution { + /// 定义两个指针 p1, p2,如果p1 != p2, 则可以移除p1或者p2, 这时只要p1..p2-1 或者p1+1..p2这两个子串是回文串即可以满足删除一行是回文串的需求。 + pub fn valid_palindrome(s: String) -> bool { + Self::valid(s.as_bytes(), false) + } + + fn valid(s: &[u8], flag: bool) -> bool { + if s.is_empty() { + return true; + } + let (mut start, mut end) = (0, s.len() - 1); + while start < end { + if s[start] == s[end] { + start += 1; + end -= 1; + } else { + if !flag { + return Self::valid(&s[start + 1..=end], true) + || Self::valid(&s[start..=end - 1], true); + } + + return false; + } + } + + true + } +} diff --git a/src/bin/VabMRr.rs b/src/bin/VabMRr.rs new file mode 100644 index 00000000..665d5576 --- /dev/null +++ b/src/bin/VabMRr.rs @@ -0,0 +1,65 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() { + assert_eq!( + Solution::find_anagrams("cbaebabacd".into(), "abc".into()), + vec![0, 6] + ); + assert_eq!( + Solution::find_anagrams("abab".into(), "ab".into()), + vec![0, 1, 2] + ); +} + +struct Solution; + +impl Solution { + pub fn find_anagrams(s: String, p: String) -> Vec { + if s.len() < p.len() { + return vec![]; + } + let mut v = [0; 26]; + for i in 0..p.len() { + v[(s.as_bytes()[i] - b'a') as usize] += 1; + v[(p.as_bytes()[i] - b'a') as usize] -= 1; + } + + let mut ans = vec![]; + let mut diff = 0; + for &i in v.iter() { + if i != 0 { + diff += 1; + } + } + + if diff == 0 { + ans.push(0); + } + + for i in p.len()..s.len() { + if v[(s.as_bytes()[i - p.len()] - b'a') as usize] == 0 { + diff += 1; + } + + v[(s.as_bytes()[i - p.len()] - b'a') as usize] -= 1; + if v[(s.as_bytes()[i - p.len()] - b'a') as usize] == 0 { + diff -= 1; + } + + if v[(s.as_bytes()[i] - b'a') as usize] == 0 { + diff += 1; + } + + v[(s.as_bytes()[i] - b'a') as usize] += 1; + if v[(s.as_bytes()[i] - b'a') as usize] == 0 { + diff -= 1; + } + + if diff == 0 { + ans.push((i - p.len() + 1) as i32); + } + } + + ans + } +} diff --git a/src/bin/WGki4K.rs b/src/bin/WGki4K.rs new file mode 100644 index 00000000..d020177b --- /dev/null +++ b/src/bin/WGki4K.rs @@ -0,0 +1,65 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() { + assert_eq!(Solution::single_number(vec![2, 2, 3, 2]), 3); + assert_eq!(Solution::single_number(vec![0, 1, 0, 1, 0, 1, 100]), 100); + assert_eq!( + Solution::single_number(vec![-2, -2, 1, 1, 4, 1, 4, 4, -4, -2]), + -4 + ); + assert_eq!( + Solution::single_number(vec![ + 43, + 16, + 45, + 89, + 45, + -2147483648, + 45, + 2147483646, + -2147483647, + -2147483648, + 43, + 2147483647, + -2147483646, + -2147483648, + 89, + -2147483646, + 89, + -2147483646, + -2147483647, + 2147483646, + -2147483647, + 16, + 16, + 2147483646, + 43 + ]), + 2147483647 + ); +} + +struct Solution; + +impl Solution { + pub fn single_number(nums: Vec) -> i32 { + let mut v = [0; std::mem::size_of::() * 8]; + + for mut i in nums { + for j in 0..32 { + if (i >> j) & 1 == 1 { + v[j] = (v[j] + 1) % 3; + } + } + } + + let mut ans = 0; + for i in 0..v.len() { + if v[i] == 1 { + ans += (1 << i); + } + } + + ans + } +} diff --git a/src/bin/WHnhjV.rs b/src/bin/WHnhjV.rs new file mode 100644 index 00000000..71aef651 --- /dev/null +++ b/src/bin/WHnhjV.rs @@ -0,0 +1,23 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn give_gem(mut gem: Vec, operations: Vec>) -> i32 { + for i in operations { + gem[i[1] as usize] += gem[i[0] as usize] / 2; + gem[i[0] as usize] -= gem[i[0] as usize] / 2; + } + + let (mut max, mut min) = (gem[0], gem[0]); + + for i in 1..gem.len() { + max = max.max(gem[i]); + min = min.min(gem[i]); + } + + max - min + } +} diff --git a/src/bin/WNC0Lk.rs b/src/bin/WNC0Lk.rs new file mode 100644 index 00000000..cba13d42 --- /dev/null +++ b/src/bin/WNC0Lk.rs @@ -0,0 +1,54 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +// Definition for a binary tree node. +#[derive(Debug, PartialEq, Eq)] +pub struct TreeNode { + pub val: i32, + pub left: Option>>, + pub right: Option>>, +} + +impl TreeNode { + #[inline] + pub fn new(val: i32) -> Self { + TreeNode { + val, + left: None, + right: None, + } + } +} +use std::borrow::BorrowMut; +use std::cell::RefCell; +use std::rc::Rc; +impl Solution { + pub fn right_side_view(root: Option>>) -> Vec { + let mut ans = vec![]; + let mut stack = vec![]; + if root.is_some() { + stack.push(root); + } + + while !stack.is_empty() { + let mut new_stack = vec![]; + ans.push(stack[stack.len() - 1].as_deref().unwrap().borrow().val); + for i in 0..stack.len() { + if stack[i].as_deref().unwrap().borrow().left.is_some() { + new_stack.push(stack[i].as_deref().unwrap().borrow_mut().left.take()); + } + + if stack[i].as_deref().unwrap().borrow().right.is_some() { + new_stack.push(stack[i].as_deref().unwrap().borrow_mut().right.take()); + } + } + + stack = new_stack; + } + + ans + } +} diff --git a/src/bin/XagZNi.rs b/src/bin/XagZNi.rs new file mode 100644 index 00000000..8215eaef --- /dev/null +++ b/src/bin/XagZNi.rs @@ -0,0 +1,52 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +use std::vec; + +fn main() { + assert_eq!(Solution::asteroid_collision(vec![5, 10, -5]), vec![5, 10]); + assert_eq!(Solution::asteroid_collision(vec![8, -8]), vec![]); + assert_eq!(Solution::asteroid_collision(vec![10, 2, -5]), vec![10]); + assert_eq!( + Solution::asteroid_collision(vec![-2, -1, 1, 2]), + vec![-2, -1, 1, 2] + ); +} + +struct Solution; + +impl Solution { + pub fn asteroid_collision(asteroids: Vec) -> Vec { + let mut v = vec![]; + + for i in asteroids { + v.push(i); + while v.len() > 1 { + let l1 = v[v.len() - 1]; + if l1 > 0 { + break; + } + + let l2 = v[v.len() - 2]; + + if l1 < 0 && l2 > 0 { + if l1.abs() > l2 { + let i = v.len() - 2; + v[i] = l1; + v.pop(); + } else if l1.abs() == l2 { + v.pop(); + v.pop(); + break; + } else { + v.pop(); + break; + } + } else { + break; + } + } + } + + v + } +} diff --git a/src/bin/XltzEq.rs b/src/bin/XltzEq.rs new file mode 100644 index 00000000..2653db82 --- /dev/null +++ b/src/bin/XltzEq.rs @@ -0,0 +1,54 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() { + assert!(Solution::is_palindrome( + "A man, a plan, a canal: Panama".into() + )); + assert!(!Solution::is_palindrome("race a car".into())); +} + +struct Solution; + +impl Solution { + pub fn is_palindrome(s: String) -> bool { + if s.is_empty() { + return true; + } + + let (mut start, mut end) = (0, s.len() - 1); + let s = s.as_bytes(); + + while start < end { + if matches!(s[start], b'a'..=b'z' | b'A'..=b'Z' | b'0'..=b'9') + && matches!(s[end], b'a'..=b'z' | b'A'..=b'Z' | b'0'..=b'9') + { + if s[start] == s[end] { + start += 1; + end -= 1; + } else if matches!(s[start], b'a'..=b'z') + && matches!(s[end], b'A'..=b'Z') + && s[end] + 32 == s[start] + { + start += 1; + end -= 1; + } else if matches!(s[end], b'a'..=b'z') + && matches!(s[start], b'A'..=b'Z') + && s[start] + 32 == s[end] + { + start += 1; + end -= 1; + } else { + return false; + } + } else if !matches!(s[start], b'a'..=b'z' | b'A'..=b'Z' | b'0'..=b'9') { + start += 1; + } else if !matches!(s[end], b'a'..=b'z' | b'A'..=b'Z' | b'0'..=b'9') { + end -= 1; + } else { + unreachable!() + } + } + + true + } +} diff --git a/src/bin/YaVDxD.rs b/src/bin/YaVDxD.rs new file mode 100644 index 00000000..59f4eb82 --- /dev/null +++ b/src/bin/YaVDxD.rs @@ -0,0 +1,23 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn find_target_sum_ways(nums: Vec, target: i32) -> i32 { + Self::f(&nums[..], target) + } + + fn f(nums: &[i32], target: i32) -> i32 { + if nums.len() == 0 { + if target == 0 { + return 1; + } else { + return 0; + } + } + + Self::f(&nums[1..], target - nums[0]) + Self::f(&nums[1..], target + nums[0]) + } +} diff --git a/src/bin/ZVAVXX.rs b/src/bin/ZVAVXX.rs new file mode 100644 index 00000000..f0b4de9b --- /dev/null +++ b/src/bin/ZVAVXX.rs @@ -0,0 +1,43 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() { + assert_eq!( + Solution::num_subarray_product_less_than_k(vec![10, 5, 2, 6], 100), + 8 + ); + assert_eq!( + Solution::num_subarray_product_less_than_k(vec![1, 2, 3], 0), + 0 + ); + + assert_eq!( + Solution::num_subarray_product_less_than_k(vec![1, 1, 1], 2), + 6 + ); +} + +struct Solution; + +impl Solution { + /// 两个指针 start和end,start和end的子数组的积为 product + /// 先以start为起点,递增end,判断 product 是否满足条件,不满足条件的时候停止递增 + /// 然后递增start,直到start等于end为止, + /// 然后重复2,3步直到最后一步 + pub fn num_subarray_product_less_than_k(nums: Vec, k: i32) -> i32 { + let mut start = 0; + let mut product = 1; + let mut ans = 0; + for (i, &v) in nums.iter().enumerate() { + product *= v; + + while start <= i && product >= k { + product /= nums[start]; + start += 1; + } + + ans += (i as i32 - start as i32) + 1; + } + + ans + } +} diff --git a/src/bin/a7VOhD.rs b/src/bin/a7VOhD.rs new file mode 100644 index 00000000..3b44c6af --- /dev/null +++ b/src/bin/a7VOhD.rs @@ -0,0 +1,43 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() { + assert_eq!(Solution::count_substrings("abc".into()), 3); + assert_eq!(Solution::count_substrings("aaa".into()), 6); +} + +struct Solution; + +impl Solution { + /// dp[i][j] = bool, 表示子串s[i..j] 是否为回文字符串 + /// - dp[i+1][j-1] && s[i] == s[j], j - i > 1 + /// - + /// dp[i][j] + /// - + /// - s[i] == s[j], j-i==1 + /// + pub fn count_substrings(s: String) -> i32 { + let mut dp = vec![vec![false; s.len()]; s.len()]; + let mut ans = 0; + + let mut len = 0; + let s = s.as_bytes(); + + while len <= s.len() { + for i in 0..s.len() - len { + if len <= 1 { + dp[i][i + len] = s[i] == s[i + len]; + } else { + dp[i][i + len] = s[i] == s[i + len] && dp[i + 1][i + len - 1]; + } + + if dp[i][i + len] { + ans += 1; + } + } + + len += 1; + } + + ans + } +} diff --git a/src/bin/aMhZSa.rs b/src/bin/aMhZSa.rs new file mode 100644 index 00000000..8567f3c7 --- /dev/null +++ b/src/bin/aMhZSa.rs @@ -0,0 +1,60 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +// Definition for singly-linked list. +#[derive(PartialEq, Eq, Clone, Debug)] +pub struct ListNode { + pub val: i32, + pub next: Option>, +} + +impl ListNode { + #[inline] + fn new(val: i32) -> Self { + ListNode { next: None, val } + } +} +impl Solution { + /// 找到下半部分,翻转上半部分,再比较上下两部分 + pub fn is_palindrome(mut head: Option>) -> bool { + let mut len = 0; + let mut current = head.as_deref(); + + while current.is_some() { + len += 1; + current = current.unwrap().next.as_deref(); + } + + let mut dummy = Box::new(ListNode::new(-1)); + + for i in 0..len / 2 { + let next = head.as_deref_mut().unwrap().next.take(); + let n = dummy.next.take(); + head.as_deref_mut().unwrap().next = n; + dummy.next = head; + head = next; + } + + let (mut left, mut right) = if len % 2 == 0 { + (dummy.next.take(), head) + } else { + (dummy.next.take(), head.unwrap().next.take()) + }; + + loop { + match (left, right) { + (Some(mut x), Some(mut y)) if x.val == y.val => { + left = x.next.take(); + right = y.next.take(); + } + (None, None) => break, + _ => return false, + } + } + + true + } +} diff --git a/src/bin/account-balance-after-rounded-purchase.rs b/src/bin/account-balance-after-rounded-purchase.rs new file mode 100644 index 00000000..84992ff1 --- /dev/null +++ b/src/bin/account-balance-after-rounded-purchase.rs @@ -0,0 +1,16 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn account_balance_after_purchase(purchase_amount: i32) -> i32 { + let a = purchase_amount % 10; + 100 - if a >= 5 { + purchase_amount + (10 - a) + } else { + purchase_amount - a + } + } +} diff --git a/src/bin/add-binary.rs b/src/bin/add-binary.rs new file mode 100644 index 00000000..96319c52 --- /dev/null +++ b/src/bin/add-binary.rs @@ -0,0 +1,61 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn add_binary(a: String, b: String) -> String { + if a == b && a == "0".to_string() { + return a; + } + + let (a, b) = (a.as_bytes(), b.as_bytes()); + let mut s = vec![b' '; a.len().max(b.len()) + 1]; + let (mut m, mut index) = ((b'0', b'0'), 0); + + while a.len() >= index || b.len() >= index { + let a1 = if a.len() >= index { + a[a.len() - index - 1] + } else { + b'0' + }; + + let b1 = if b.len() >= index { + b[b.len() - index - 1] + } else { + b'0' + }; + + m = Self::add(a1, b1, m.1); + let l = s.len() - index - 1; + s[l] = m.0; + index += 1; + } + + if m.1 == b'1' { + let l = s.len() - index - 1; + s[l] = b'1'; + } + + String::from_utf8(s) + .unwrap() + .trim_start_matches('0') + .to_string() + } + + /// 返回a+b的和与进制 + fn add(a: u8, b: u8, c: u8) -> (u8, u8) { + match (a, b, c) { + (b'1', b'1', b'1') => (b'1', b'1'), + (b'0', b'1', b'1') => (b'0', b'1'), + (b'1', b'0', b'1') => (b'0', b'1'), + (b'1', b'1', b'0') => (b'0', b'1'), + (b'0', b'0', b'1') => (b'1', b'0'), + (b'0', b'1', b'0') => (b'1', b'0'), + (b'1', b'0', b'0') => (b'1', b'0'), + (b'0', b'0', b'0') => (b'0', b'0'), + _ => (b'0', b'0'), + } + } +} diff --git a/src/bin/add-digits.rs b/src/bin/add-digits.rs new file mode 100644 index 00000000..696ba075 --- /dev/null +++ b/src/bin/add-digits.rs @@ -0,0 +1,40 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + println!("{}", Solution::add_digits(38)); + println!("{}", Solution::add_digits(3143243)); +} + +struct Solution; + +impl Solution { + // 超出时间限制 + pub fn add_digits1(num: i32) -> i32 { + if num < 10 { + return num; + } + + let mut num = num; + let mut s = 0; + while num > 10 { + s += num % 10; + num /= 10; + } + + Self::add_digits(s + num) + } + + /// 能够被9整除的整数,各位上的数字加起来也必然能被9整除,所以,连续累加起来,最终必然就是9。 + /// 不能被9整除的整数,各位上的数字加起来,结果对9取模,和初始数对9取摸,是一样的,所以,连续累加起来,最终必然就是初始数对9取摸。 + pub fn add_digits(num: i32) -> i32 { + if num % 9 == 0 { + if num == 0 { + 0 + } else { + 9 + } + } else { + num % 9 + } + } +} diff --git a/src/bin/add-one-row-to-tree.rs b/src/bin/add-one-row-to-tree.rs new file mode 100644 index 00000000..e712dcda --- /dev/null +++ b/src/bin/add-one-row-to-tree.rs @@ -0,0 +1,69 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +// Definition for a binary tree node. +#[derive(Debug, PartialEq, Eq)] +pub struct TreeNode { + pub val: i32, + pub left: Option>>, + pub right: Option>>, +} + +impl TreeNode { + #[inline] + pub fn new(val: i32) -> Self { + TreeNode { + val, + left: None, + right: None, + } + } +} + +use std::cell::RefCell; +use std::rc::Rc; + +impl Solution { + pub fn add_one_row( + root: Option>>, + val: i32, + depth: i32, + ) -> Option>> { + Self::add(root, val, depth, true) + } + + fn add( + root: Option>>, + val: i32, + depth: i32, + is_left: bool, + ) -> Option>> { + if depth == 1 { + let mut node = TreeNode::new(val); + if is_left { + node.left = root; + } else { + node.right = root; + } + Some(Rc::new(RefCell::new(node))) + } else { + if root.is_none() { + return None; + } + + let left = root.as_ref().unwrap().borrow_mut().left.take(); + let left = Self::add(left, val, depth - 1, true); + + let right = root.as_ref().unwrap().borrow_mut().right.take(); + let right = Self::add(right, val, depth - 1, false); + + root.as_ref().unwrap().borrow_mut().left = left; + root.as_ref().unwrap().borrow_mut().right = right; + + root + } + } +} diff --git a/src/bin/add-strings.rs b/src/bin/add-strings.rs new file mode 100644 index 00000000..2c6f990d --- /dev/null +++ b/src/bin/add-strings.rs @@ -0,0 +1,56 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn add_strings(num1: String, num2: String) -> String { + let mut i = 0u8; // 进制 + let (num1, num2) = (num1.as_bytes(), num2.as_bytes()); + let (mut i1, mut i2) = (num1.len(), num2.len()); + + let mut v = vec![0u8; i1.max(i2) + 1]; + let mut vindex = v.len() - 1; + + loop { + let a = if i1 == 0 && i2 > 0 { + i2 -= 1; + num2[i2] - b'0' + i + } else if i1 > 0 && i2 == 0 { + i1 -= 1; + num1[i1] - b'0' + i + } else { + i2 -= 1; + i1 -= 1; + num1[i1] + num2[i2] - b'0' - b'0' + i + }; + + if a >= 10 { + v[vindex] = a - 10; + i = 1; + } else { + v[vindex] = a; + i = 0; + } + + if i1 == 0 && i2 == 0 { + break; + } + + vindex -= 1; + } + + if i != 0 { + vindex -= 1; + v[vindex] = 1; + } + + v[vindex..] + .iter() + .fold(String::with_capacity((&v[vindex..]).len()), |mut x, y| { + x.push_str(&*y.to_string()); + x + }) + } +} diff --git a/src/bin/add-two-numbers-ii.rs b/src/bin/add-two-numbers-ii.rs new file mode 100644 index 00000000..d5151644 --- /dev/null +++ b/src/bin/add-two-numbers-ii.rs @@ -0,0 +1,79 @@ +#![allow(dead_code, unused, unused_variables)] + +use std::borrow::Borrow; + +fn main() {} + +struct Solution; + +// Definition for singly-linked list. +#[derive(PartialEq, Eq, Clone, Debug)] +pub struct ListNode { + pub val: i32, + pub next: Option>, +} + +impl ListNode { + #[inline] + fn new(val: i32) -> Self { + ListNode { next: None, val } + } +} + +impl Solution { + pub fn add_two_numbers( + l1: Option>, + l2: Option>, + ) -> Option> { + let (mut l1, mut l2) = (l1, l2); + let (mut v1, mut v2) = (vec![], vec![]); + + while l1.is_some() || l2.is_some() { + if let Some(mut x) = l1 { + v1.push(x.val); + l1 = x.next.take(); + } + + if let Some(mut x) = l2 { + v2.push(x.val); + l2 = x.next.take(); + } + } + + let mut i = 0; // 进制 + let mut new_node = None; + loop { + match (v1.pop(), v2.pop()) { + (Some(a), Some(b)) => { + let mut n = ListNode::new((a + b + i) % 10); + n.next = new_node.take(); + new_node = Some(Box::new(n)); + i = (a + b + i) / 10; + } + (Some(a), None) => { + let mut n = ListNode::new((a + i) % 10); + n.next = new_node.take(); + new_node = Some(Box::new(n)); + i = (a + i) / 10; + } + (None, Some(b)) => { + let mut n = ListNode::new((b + i) % 10); + n.next = new_node.take(); + new_node = Some(Box::new(n)); + i = (b + i) / 10; + } + + (None, None) => { + if i > 0 { + let mut n = ListNode::new(i); + n.next = new_node.take(); + new_node = Some(Box::new(n)); + } + break; + } + } + } + + new_node + } +} diff --git a/src/bin/add-two-numbers.rs b/src/bin/add-two-numbers.rs new file mode 100644 index 00000000..94078959 --- /dev/null +++ b/src/bin/add-two-numbers.rs @@ -0,0 +1,67 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +// Definition for singly-linked list. +#[derive(PartialEq, Eq, Clone, Debug)] +pub struct ListNode { + pub val: i32, + pub next: Option>, +} + +impl ListNode { + #[inline] + fn new(val: i32) -> Self { + ListNode { next: None, val } + } +} + +impl Solution { + pub fn add_two_numbers( + l1: Option>, + l2: Option>, + ) -> Option> { + Self::re(l1, l2, 0) + } + + /// base: 进制,相加和大于10进制 + fn re( + l1: Option>, + l2: Option>, + base: i32, + ) -> Option> { + if l1.is_none() && l2.is_none() { + if base == 0 { + return None; + } else { + return Some(Box::new(ListNode::new(base))); + } + } + + let (mut result, mut value) = (ListNode::new(0), None); + if l1.is_none() { + let mut l2 = l2.unwrap(); + result.val = (l2.val + base) % 10; + let base = (l2.val + base) / 10; + value = Self::re(None, l2.next.take(), base); + } else if l2.is_none() { + let mut l1 = l1.unwrap(); + result.val = (l1.val + base) % 10; + let base = (l1.val + base) / 10; + value = Self::re(l1.next.take(), None, base); + } else { + let mut l1 = l1.unwrap(); + let mut l2 = l2.unwrap(); + result.val = (l1.val + l2.val + base) % 10; + let base = (l1.val + l2.val + base) / 10; + value = Self::re(l1.next.take(), l2.next.take(), base); + } + + if value.is_some() { + result.next = value; + } + Some(Box::new(result)) + } +} diff --git a/src/bin/add-without-plus-lcci.rs b/src/bin/add-without-plus-lcci.rs new file mode 100644 index 00000000..ea98068c --- /dev/null +++ b/src/bin/add-without-plus-lcci.rs @@ -0,0 +1,16 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn add(mut a: i32, mut b: i32) -> i32 { + while b != 0 { + let mut carry = (a & b) << 1 as u32; + a ^= b; + b = carry; + } + a + } +} diff --git a/src/bin/airplane-seat-assignment-probability.rs b/src/bin/airplane-seat-assignment-probability.rs new file mode 100644 index 00000000..eb9db8cd --- /dev/null +++ b/src/bin/airplane-seat-assignment-probability.rs @@ -0,0 +1,15 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn nth_person_gets_nth_seat(n: i32) -> f64 { + if n == 1 { + return 1f64; + } + + 0.5 + } +} diff --git a/src/bin/all-divisions-with-the-highest-score-of-a-binary-array.rs b/src/bin/all-divisions-with-the-highest-score-of-a-binary-array.rs new file mode 100644 index 00000000..1ecb3b96 --- /dev/null +++ b/src/bin/all-divisions-with-the-highest-score-of-a-binary-array.rs @@ -0,0 +1,39 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +use std::vec; + +fn main() {} + +struct Solution; + +impl Solution { + pub fn max_score_indices(nums: Vec) -> Vec { + let total_1: i32 = nums.iter().map(|x| *x).sum(); + + let mut result = vec![0]; + let (mut left_0, mut right_1) = (0, total_1); + let mut max = total_1; + + for (i, v) in nums.into_iter().enumerate() { + if v == 1 { + right_1 -= 1; + } else if v == 0 { + left_0 += 1; + } + + match (left_0 + right_1).cmp(&max) { + std::cmp::Ordering::Greater => { + max = left_0 + right_1; + result = vec![i as i32 + 1]; + } + + std::cmp::Ordering::Equal => { + result.push(i as i32 + 1); + } + _ => {} + } + } + + result + } +} diff --git a/src/bin/all-elements-in-two-binary-search-trees.rs b/src/bin/all-elements-in-two-binary-search-trees.rs new file mode 100644 index 00000000..a3831a02 --- /dev/null +++ b/src/bin/all-elements-in-two-binary-search-trees.rs @@ -0,0 +1,84 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +use std::cell::RefCell; +use std::rc::Rc; + +fn main() {} + +struct Solution; + +// Definition for a binary tree node. +#[derive(Debug, PartialEq, Eq)] +pub struct TreeNode { + pub val: i32, + pub left: Option>>, + pub right: Option>>, +} + +impl TreeNode { + #[inline] + pub fn new(val: i32) -> Self { + TreeNode { + val, + left: None, + right: None, + } + } +} + +impl Solution { + pub fn get_all_elements( + root1: Option>>, + root2: Option>>, + ) -> Vec { + let r1 = Self::get_list(root1); + let r2 = Self::get_list(root2); + + let mut result = Vec::with_capacity(r1.len() + r2.len()); + let (mut i1, mut i2) = (0, 0); + while i1 < r1.len() || i2 < r2.len() { + match (r1.get(i1), r2.get(i2)) { + (Some(&x), Some(&y)) => { + if x <= y { + result.push(x); + i1 += 1; + } else { + result.push(y); + i2 += 1; + } + } + + (Some(&x), _) => { + result.push(x); + i1 += 1; + } + + (_, Some(&y)) => { + result.push(y); + i2 += 1; + } + _ => unreachable!(), + } + } + + result + } + + fn get_list(root: Option>>) -> Vec { + fn f(root: Option>>, r: &mut Vec) { + if root.is_none() { + return; + } + + let root = root.unwrap(); + f(root.borrow_mut().left.take(), r); + r.push(root.borrow().val); + f(root.borrow_mut().right.take(), r); + } + + let mut result = vec![]; + f(root, &mut result); + + result + } +} diff --git a/src/bin/all-possible-full-binary-trees.rs b/src/bin/all-possible-full-binary-trees.rs new file mode 100644 index 00000000..26932724 --- /dev/null +++ b/src/bin/all-possible-full-binary-trees.rs @@ -0,0 +1,61 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +use std::cell::RefCell; +use std::rc::Rc; + +// Definition for a binary tree node. +#[derive(Debug, PartialEq, Eq)] +pub struct TreeNode { + pub val: i32, + pub left: Option>>, + pub right: Option>>, +} + +impl TreeNode { + #[inline] + pub fn new(val: i32) -> Self { + TreeNode { + val, + left: None, + right: None, + } + } +} + +fn main() {} + +struct Solution; + +impl Solution { + /// 递归,n为偶数肯定不行 + /// 假设左节点按1,3,5递增 + /// 则右节点数为n-1-1,n-1-3,n-1-5 + pub fn all_possible_fbt(n: i32) -> Vec>>> { + let mut v = vec![]; + if n % 2 == 0 { + return v; + } + + if n == 1 { + v.push(Some(Rc::new(RefCell::new(TreeNode::new(0))))); + return v; + } + + for i in (1..=n - 2).step_by(2) { + let left = Self::all_possible_fbt(i); + let right = Self::all_possible_fbt(n - i - 1); + + for l in left.iter() { + for r in right.iter() { + let mut root = Rc::new(RefCell::new(TreeNode::new(0))); + root.borrow_mut().left = l.clone(); + root.borrow_mut().right = r.clone(); + + v.push(Some(root)) + } + } + } + + v + } +} diff --git a/src/bin/alphabet-board-path.rs b/src/bin/alphabet-board-path.rs new file mode 100644 index 00000000..c4e815f3 --- /dev/null +++ b/src/bin/alphabet-board-path.rs @@ -0,0 +1,40 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn alphabet_board_path(target: String) -> String { + let mut v = String::new(); + let mut start = (0i32, 0i32); + for i in target.as_bytes().iter().map(|x| (*x) as i32) { + let t = ((i - 97) / 5, (i - 97) % 5); + let interval = (t.0 - start.0, t.1 - start.1); + + if interval.0 > 0 { + v.push_str("D".repeat((interval.0 - t.0 / 5) as usize).as_str()) + } else { + v.push_str("U".repeat((-1 * interval.0) as usize).as_str()) + } + + if interval.1 > 0 { + v.push_str("R".repeat(interval.1 as usize).as_str()) + } else { + v.push_str("L".repeat((-1 * interval.1) as usize).as_str()) + } + + if i == b'z' as i32 { + if interval.0 != 0 && t.0 / 5 > 0 { + v.push('D'); + } + } + + v.push('!'); + + start = t; + } + + v + } +} diff --git a/src/bin/alternating-digit-sum.rs b/src/bin/alternating-digit-sum.rs new file mode 100644 index 00000000..5d89fcd3 --- /dev/null +++ b/src/bin/alternating-digit-sum.rs @@ -0,0 +1,28 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn alternate_digit_sum(mut n: i32) -> i32 { + let mut r = 0; + let mut flag = true; + while n > 0 { + if flag { + r += n % 10; + } else { + r -= n % 10; + } + + n /= 10; + flag = !flag; + } + + if !flag { + r + } else { + -r + } + } +} diff --git a/src/bin/ambiguous-coordinates.rs b/src/bin/ambiguous-coordinates.rs new file mode 100644 index 00000000..7d14334f --- /dev/null +++ b/src/bin/ambiguous-coordinates.rs @@ -0,0 +1,71 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn ambiguous_coordinates(s: String) -> Vec { + let s = &s[1..s.len() - 1]; + let mut result = vec![]; + for i in 0..s.len() { + let s1 = Self::get_num(&s[..i]); + let s2 = Self::get_num(&s[i..]); + + for j in s1.iter() { + for k in s2.iter() { + result.push(format!("({j}, {k})")); + } + } + } + + result + } + + fn get_num(s: &str) -> Vec { + let mut r = vec![]; + if s.is_empty() { + return r; + } + + if s.as_bytes()[0] != b'0' || s.len() == 1 { + r.push(String::from(s)); + } + + for i in 1..s.len() { + if Self::is_valid_1(&s[..i]) && Self::is_valid_2(&s[i..]) { + r.push(format!("{}.{}", &s[..i], &s[i..])) + } + } + + r + } + + fn is_valid_1(s: &str) -> bool { + if s.is_empty() { + return false; + } + + if s.len() == 1 { + return true; + } + + if s.as_bytes()[0] == b'0' { + return false; + } + + true + } + + fn is_valid_2(s: &str) -> bool { + if s.is_empty() { + return false; + } + + if s.as_bytes()[s.len() - 1] == b'0' { + return false; + } + + true + } +} diff --git a/src/bin/amount-of-time-for-binary-tree-to-be-infected.rs b/src/bin/amount-of-time-for-binary-tree-to-be-infected.rs new file mode 100644 index 00000000..a3c0d3d9 --- /dev/null +++ b/src/bin/amount-of-time-for-binary-tree-to-be-infected.rs @@ -0,0 +1,76 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +use std::cell::RefCell; +use std::rc::Rc; + +fn main() {} + +struct Solution; + +// Definition for a binary tree node. +#[derive(Debug, PartialEq, Eq)] +pub struct TreeNode { + pub val: i32, + pub left: Option>>, + pub right: Option>>, +} + +impl TreeNode { + #[inline] + pub fn new(val: i32) -> Self { + TreeNode { + val, + left: None, + right: None, + } + } +} + +impl Solution { + /// hashmap记录与节点所有相连的值 + /// 然后在dfs这个hashmap + pub fn amount_of_time(root: Option>>, start: i32) -> i32 { + let mut hash = std::collections::HashMap::>::new(); + + Self::dfs1(&mut hash, root, None); + Self::dfs2(&hash, start, -1) + } + + pub fn dfs1( + hash: &mut std::collections::HashMap>, + root: Option>>, + parent: Option, + ) { + if root.is_none() { + return; + } + + let root = root.unwrap(); + let value = root.borrow().val; + + if let Some(i) = parent { + hash.entry(value).or_insert(vec![]).push(i); + hash.entry(i).or_insert(vec![]).push(value); + } + + Self::dfs1(hash, root.borrow_mut().left.take(), Some(value)); + Self::dfs1(hash, root.borrow_mut().right.take(), Some(value)); + } + + pub fn dfs2(hash: &std::collections::HashMap>, start: i32, last: i32) -> i32 { + match hash.get(&start) { + Some(v) => { + let mut r = 0; + for &i in v { + if i == last { + continue; + } + r = r.max(1 + Self::dfs2(hash, i, start)); + } + + r + } + None => 0, + } + } +} diff --git a/src/bin/apple-redistribution-into-boxes.rs b/src/bin/apple-redistribution-into-boxes.rs new file mode 100644 index 00000000..4fcc6750 --- /dev/null +++ b/src/bin/apple-redistribution-into-boxes.rs @@ -0,0 +1,23 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn minimum_boxes(apple: Vec, capacity: Vec) -> i32 { + let mut total: i32 = apple.into_iter().sum(); + let mut capacity = capacity; + capacity.sort(); + let mut result = 0; + while let Some(x) = capacity.pop() { + total -= x; + result += 1; + if total <= 0 { + break; + } + } + + result + } +} diff --git a/src/bin/apply-discount-to-prices.rs b/src/bin/apply-discount-to-prices.rs new file mode 100644 index 00000000..e551e405 --- /dev/null +++ b/src/bin/apply-discount-to-prices.rs @@ -0,0 +1,33 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn discount_prices(sentence: String, discount: i32) -> String { + let mut result = String::new(); + + for mut s in sentence.split(' ') { + if s.starts_with('$') { + result.push('$'); + s = &s[1..]; + + match s.parse::() { + Ok(i) => result.push_str(&format!( + "{:.2}", + i as f64 * (1.0 - discount as f64 / 100.0) + )), + _ => result.push_str(s), + } + } else { + result.push_str(s); + } + + result.push(' '); + } + + result.pop(); + result + } +} diff --git a/src/bin/apply-operations-to-an-array.rs b/src/bin/apply-operations-to-an-array.rs new file mode 100644 index 00000000..20294f60 --- /dev/null +++ b/src/bin/apply-operations-to-an-array.rs @@ -0,0 +1,33 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn apply_operations(mut nums: Vec) -> Vec { + for i in 0..nums.len() - 1 { + if nums[i] == nums[i + 1] { + nums[i] *= 2; + nums[i + 1] = 0; + } + } + + // i: 第一个0的下标 + let mut i = 0; + + for j in 0..nums.len() { + if nums[j] != 0 { + while i < j { + if nums[i] == 0 { + nums.swap(i, j); + break; + } + i += 1; + } + } + } + + nums + } +} diff --git a/src/bin/arithmetic-slices.rs b/src/bin/arithmetic-slices.rs new file mode 100644 index 00000000..2c709f42 --- /dev/null +++ b/src/bin/arithmetic-slices.rs @@ -0,0 +1,48 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + println!( + "{}", + Solution::number_of_arithmetic_slices(vec![1, 2, 3, 4]) + ); + println!( + "{}", + Solution::number_of_arithmetic_slices(vec![1, 2, 3, 4, 5, 6]) + ); + println!( + "{}", + Solution::number_of_arithmetic_slices(vec![1, 2, 3, 4, 10, 11, 12, 13]) + ); +} + +struct Solution; + +impl Solution { + pub fn number_of_arithmetic_slices(nums: Vec) -> i32 { + if nums.len() < 3 { + return 0; + } + + let mut count = 0; + let mut num = 2; + let mut s = nums[1] - nums[0]; + + for i in 2..nums.len() { + if nums[i] - nums[i - 1] == s { + num += 1; + } else { + if num >= 3 { + count += (1..=num - 3 + 1).into_iter().sum::(); + } + s = nums[i] - nums[i - 1]; + num = 2; + } + } + + if num >= 3 { + count += (1..=num - 3 + 1).into_iter().sum::(); + } + + count + } +} diff --git a/src/bin/array-nesting.rs b/src/bin/array-nesting.rs new file mode 100644 index 00000000..53151edf --- /dev/null +++ b/src/bin/array-nesting.rs @@ -0,0 +1,43 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + assert_eq!(4, Solution::array_nesting(vec![5, 4, 0, 3, 1, 6, 2])); +} + +struct Solution; + +impl Solution { + pub fn array_nesting(nums: Vec) -> i32 { + let mut count = 0; + let mut s = vec![0; nums.len()]; + + for i in 0..nums.len() { + let n = Self::f(&nums[..], &mut s[..], i, nums[i]); + if n > count { + count = n; + } + + s[i as usize] = n; + + if count == nums.len() as i32 { + break; + } + } + + count + } + + fn f(nums: &[i32], s: &mut [i32], n: usize, n1: i32) -> i32 { + if n == n1 as usize { + return 1; + } + + if s[n as usize] != 0 { + return s[n as usize]; + } + + let m = Self::f(nums, s, n, nums[n1 as usize]) + 1; + s[n1 as usize] = m; + m + } +} diff --git a/src/bin/aseY1I.rs b/src/bin/aseY1I.rs new file mode 100644 index 00000000..2fde032f --- /dev/null +++ b/src/bin/aseY1I.rs @@ -0,0 +1,51 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +use std::vec; + +fn main() { + assert_eq!( + Solution::max_product( + vec!["abcw", "baz", "foo", "bar", "xtfn", "abcdef"] + .into_iter() + .map(|x| x.to_string()) + .collect() + ), + 16 + ) +} + +struct Solution; + +impl Solution { + /// 用一个i32表示 b'a' - b'z' 存在的数,比如存在b'a',则此i32的最低位为1 + /// 然后两个数相与的结果为0的话则表示不存在相同的字母。 + /// 然后长度相乘得到结果。 + pub fn max_product(words: Vec) -> i32 { + let v = words + .iter() + .map(|s| { + let mut i = 0; + for x in s.as_bytes() { + i |= (1 << (x - b'a')); + } + i + }) + .collect::>(); + + let mut ans = 0; + + for i in 0..v.len() { + for j in 0..v.len() { + if i == j { + continue; + } + + if v[i] & v[j] == 0 { + ans = ans.max(words[i].len() * words[j].len()); + } + } + } + + ans as i32 + } +} diff --git a/src/bin/available-captures-for-rook.rs b/src/bin/available-captures-for-rook.rs new file mode 100644 index 00000000..d036bd24 --- /dev/null +++ b/src/bin/available-captures-for-rook.rs @@ -0,0 +1,66 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn num_rook_captures(board: Vec>) -> i32 { + let mut index = (0usize, 0usize); + for i in 0..board.len() { + for j in 0..board[0].len() { + if board[i][j] == 'R' { + index = (i, j); + break; + } + } + } + let mut result = 0; + + for i in (0..index.0).rev() { + match board[i][index.1] { + 'B' => break, + 'p' => { + result += 1; + break; + } + _ => {} + } + } + + for i in (index.0..board.len()) { + match board[i][index.1] { + 'B' => break, + 'p' => { + result += 1; + break; + } + _ => {} + } + } + + for i in (0..index.1).rev() { + match board[index.0][i] { + 'B' => break, + 'p' => { + result += 1; + break; + } + _ => {} + } + } + + for i in (index.1..board[0].len()) { + match board[index.0][i] { + 'B' => break, + 'p' => { + result += 1; + break; + } + _ => {} + } + } + + result + } +} diff --git a/src/bin/average-of-levels-in-binary-tree.rs b/src/bin/average-of-levels-in-binary-tree.rs new file mode 100644 index 00000000..f3fa0aa3 --- /dev/null +++ b/src/bin/average-of-levels-in-binary-tree.rs @@ -0,0 +1,67 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +// Definition for a binary tree node. +#[derive(Debug, PartialEq, Eq)] +pub struct TreeNode { + pub val: i32, + pub left: Option>>, + pub right: Option>>, +} + +impl TreeNode { + #[inline] + pub fn new(val: i32) -> Self { + TreeNode { + val, + left: None, + right: None, + } + } +} + +use std::cell::RefCell; +use std::rc::Rc; + +impl Solution { + pub fn average_of_levels(root: Option>>) -> Vec { + if root.is_none() { + return vec![]; + } + + let mut result = vec![]; + let mut stack = vec![root]; + + while !stack.is_empty() { + let mut s = vec![]; + let mut l = stack.len(); + let mut sum = 0; + + while let Some(v) = stack.pop() { + if v.is_none() { + continue; + } + + let v = v.unwrap(); + sum += v.borrow().val as i64; + let left = v.borrow_mut().left.take(); + if left.is_some() { + s.push(left); + } + + let right = v.borrow_mut().right.take(); + if right.is_some() { + s.push(right); + } + } + + result.push(sum as f64 / l as f64); + stack = s; + } + + result + } +} diff --git a/src/bin/average-salary-excluding-the-minimum-and-maximum-salary.rs b/src/bin/average-salary-excluding-the-minimum-and-maximum-salary.rs new file mode 100644 index 00000000..6ea48ecb --- /dev/null +++ b/src/bin/average-salary-excluding-the-minimum-and-maximum-salary.rs @@ -0,0 +1,18 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn average(salary: Vec) -> f64 { + let (mut sum, mut max, mut min) = (0, i32::MIN, i32::MAX); + for &i in salary.iter() { + sum += i; + max = max.max(i); + min = min.min(i); + } + + (sum - max - min) as f64 / (salary.len() as f64 - 2f64) + } +} diff --git a/src/bin/ba-shu-zi-fan-yi-cheng-zi-fu-chuan-lcof.rs b/src/bin/ba-shu-zi-fan-yi-cheng-zi-fu-chuan-lcof.rs new file mode 100644 index 00000000..5caf98d8 --- /dev/null +++ b/src/bin/ba-shu-zi-fan-yi-cheng-zi-fu-chuan-lcof.rs @@ -0,0 +1,46 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn translate_num1(num: i32) -> i32 { + let s = num.to_string(); + let s = s.as_bytes(); + let mut count = 0; + Self::dp(s, &mut count); + count + } + + fn dp(s: &[u8], count: &mut i32) { + if s.len() == 0 { + *count += 1; + return; + } + + if s.len() >= 2 { + if s[0] == b'1' || (s[0] == b'2' && s[1] <= b'5') { + Self::dp(&s[2..], count); + } + } + Self::dp(&s[1..], count); + } + + pub fn translate_num(num: i32) -> i32 { + if num == 0 { + return 0; + } + + let mut count = 1; + count += Self::translate_num(num / 10); + + let new_num = num % 100; + if new_num >= 10 && new_num <= 25 { + count += 1; + count += Self::translate_num(num / 100); + } + + count + } +} diff --git a/src/bin/ba-shu-zu-pai-cheng-zui-xiao-de-shu-lcof.rs b/src/bin/ba-shu-zu-pai-cheng-zui-xiao-de-shu-lcof.rs new file mode 100644 index 00000000..e861d748 --- /dev/null +++ b/src/bin/ba-shu-zu-pai-cheng-zui-xiao-de-shu-lcof.rs @@ -0,0 +1,28 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() { + println!("{}", Solution::min_number(vec![10, 2])); + println!("{}", Solution::min_number(vec![3, 30, 34, 5, 9])); +} + +struct Solution; + +impl Solution { + /// 如果 x + y > y + x, 则 x > y + /// 如果 x + y < y + x, 则 x < y + pub fn min_number(nums: Vec) -> String { + let mut nums: Vec = nums.into_iter().map(|x| x.to_string()).collect(); + nums.sort_by(|x, y| { + let mut s = String::with_capacity(x.len() + y.len()); + s.push_str(&x); + s.push_str(&y); + + let mut s1 = String::with_capacity(x.len() + y.len()); + s1.push_str(&y); + s1.push_str(&x); + + s.cmp(&s1) + }); + nums.join("") + } +} diff --git a/src/bin/ba-zi-fu-chuan-zhuan-huan-cheng-zheng-shu-lcof.rs b/src/bin/ba-zi-fu-chuan-zhuan-huan-cheng-zheng-shu-lcof.rs new file mode 100644 index 00000000..afd02b06 --- /dev/null +++ b/src/bin/ba-zi-fu-chuan-zhuan-huan-cheng-zheng-shu-lcof.rs @@ -0,0 +1,63 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn str_to_int(str: String) -> i32 { + let mut r = 0i32; + let mut start = false; // 是否开始遍历 + let mut sign = 1; // 符号位 + + for &i in str.as_bytes() { + match i { + b'-' | b'+' => { + if start { + break; + } else { + sign = if i == b'-' { -1 } else { 1 }; + start = true; + } + } + b'0'..=b'9' => { + if !start { + start = true; + } + + let (r1, is_overflow) = r.overflowing_mul(10); + + if is_overflow { + if sign == 1 { + r = std::i32::MAX; + } else { + r = std::i32::MIN; + } + break; + } + + let (r1, is_overflow) = r.overflowing_add((i - b'0') as i32 * sign); + + if is_overflow { + if sign == 1 { + r = std::i32::MAX; + } else { + r = std::i32::MIN; + } + break; + } + + r = r1; + } + b' ' => { + if start { + break; + } + } + _ => break, + } + } + + r + } +} diff --git a/src/bin/balanced-binary-tree.rs b/src/bin/balanced-binary-tree.rs new file mode 100644 index 00000000..6c16aad6 --- /dev/null +++ b/src/bin/balanced-binary-tree.rs @@ -0,0 +1,66 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +// Definition for a binary tree node. +#[derive(Debug, PartialEq, Eq)] +pub struct TreeNode { + pub val: i32, + pub left: Option>>, + pub right: Option>>, +} + +impl TreeNode { + #[inline] + pub fn new(val: i32) -> Self { + TreeNode { + val, + left: None, + right: None, + } + } +} + +use std::cell::RefCell; +use std::rc::Rc; + +impl Solution { + pub fn is_balanced(root: Option>>) -> bool { + if root.is_none() { + return true; + } + + let root = root.unwrap(); + + let r1 = Rc::clone(&root); + let r2 = Rc::clone(&root); + let (x1, t1) = Self::height(RefCell::borrow_mut(&r1).left.take()); + let (x2, t2) = Self::height(RefCell::borrow_mut(&r2).right.take()); + + t1 && t2 && (x1 - x2).abs() <= 1 + } + + fn height(root: Option>>) -> (i32, bool) { + if root.is_none() { + return (0, true); + } + + let root = root.unwrap(); + + let r1 = Rc::clone(&root); + let r2 = Rc::clone(&root); + let (x1, t1) = Self::height(RefCell::borrow_mut(&r1).left.take()); + if !t1 { + return (0, false); + } + + let (x2, t2) = Self::height(RefCell::borrow_mut(&r2).right.take()); + if !t2 { + return (0, false); + } + + (x1.max(x2) + 1, (x1 - x2).abs() <= 1) + } +} diff --git a/src/bin/bao-han-minhan-shu-de-zhan-lcof.rs b/src/bin/bao-han-minhan-shu-de-zhan-lcof.rs new file mode 100644 index 00000000..6e8d7d33 --- /dev/null +++ b/src/bin/bao-han-minhan-shu-de-zhan-lcof.rs @@ -0,0 +1,61 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +use std::vec; + +fn main() {} + +struct Solution; + +struct MinStack { + stack: Vec, + min_stack: Vec, // 辅助栈存放当前栈中的最小值 +} + +/** + * `&self` means the method takes an immutable reference. + * If you need a mutable reference, change it to `&mut self` instead. + */ +impl MinStack { + /** initialize your data structure here. */ + fn new() -> Self { + Self { + stack: vec![], + min_stack: vec![], + } + } + + fn push(&mut self, x: i32) { + if self.min_stack.is_empty() { + self.min_stack.push(x); + } else { + if self.min_stack[self.min_stack.len() - 1] >= x { + self.min_stack.push(x); + } + } + + self.stack.push(x); + } + + fn pop(&mut self) { + if let Some(x) = self.stack.pop() { + if x == *self.min_stack.last().unwrap() { + self.min_stack.pop(); + } + } + } + + fn top(&self) -> i32 { + *self.stack.last().unwrap() + } + + fn min(&self) -> i32 { + *self.min_stack.last().unwrap() + } +} + +// Your MinStack object will be instantiated and called as such: +// let obj = MinStack::new(); +// obj.push(x); +// obj.pop(); +// let ret_3: i32 = obj.top(); +// let ret_4: i32 = obj.min(); diff --git a/src/bin/base-7.rs b/src/bin/base-7.rs new file mode 100644 index 00000000..5c19f73a --- /dev/null +++ b/src/bin/base-7.rs @@ -0,0 +1,30 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + assert_eq!("202".to_string(), Solution::convert_to_base7(100)); + assert_eq!("-10".to_string(), Solution::convert_to_base7(-7)); +} + +struct Solution; + +impl Solution { + pub fn convert_to_base7(num: i32) -> String { + let (mut s, mut num) = (String::new(), num); + if num < 0 { + s.push('-'); + num *= -1; + } + let mut index = 1; + let mut s1 = 0; + while num > 0 { + s1 += (num % 7) * index; + + num /= 7; + index *= 10; + } + + s.push_str(s1.to_string().as_str()); + + s + } +} diff --git a/src/bin/baseball-game.rs b/src/bin/baseball-game.rs new file mode 100644 index 00000000..8e2eda38 --- /dev/null +++ b/src/bin/baseball-game.rs @@ -0,0 +1,28 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn cal_points(operations: Vec) -> i32 { + let mut stack: Vec = vec![]; + for i in operations.iter() { + match i.as_str() { + "C" => _ = stack.pop(), + "D" => { + stack.push(stack[stack.len() - 1] * 2); + } + "+" => { + let x = stack[stack.len() - 1]; + let y = stack[stack.len() - 2]; + stack.push(x + y); + } + + m => stack.push(m.parse().unwrap()), + } + } + + stack.into_iter().sum() + } +} diff --git a/src/bin/battleships-in-a-board.rs b/src/bin/battleships-in-a-board.rs new file mode 100644 index 00000000..0410fbc9 --- /dev/null +++ b/src/bin/battleships-in-a-board.rs @@ -0,0 +1,26 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + /// 通过战舰头部的个数来判断 + /// 当'X'的上边和左边是'X',则说明这是舰身 + pub fn count_battleships(board: Vec>) -> i32 { + let mut num = 0; + + for i in 0..board.len() { + for j in 0..board[0].len() { + if board[i][j] == 'X' { + if (i > 0 && board[i - 1][j] == 'X') || (j > 0 && board[i][j - 1] == 'X') { + continue; + } + num += 1; + } + } + } + + num + } +} diff --git a/src/bin/best-sightseeing-pair.rs b/src/bin/best-sightseeing-pair.rs new file mode 100644 index 00000000..6a7ae98f --- /dev/null +++ b/src/bin/best-sightseeing-pair.rs @@ -0,0 +1,18 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn max_score_sightseeing_pair(values: Vec) -> i32 { + let mut result = values[0] + 0 + values[1] - 1; + let mut i = (values[0] + 0).max(values[1] + 1); + for index in 2..values.len() { + result = result.max(values[index] - index as i32 + i); + i = i.max(values[index] + index as i32); + } + + result + } +} diff --git a/src/bin/best-time-to-buy-and-sell-stock-ii.rs b/src/bin/best-time-to-buy-and-sell-stock-ii.rs new file mode 100644 index 00000000..1068536d --- /dev/null +++ b/src/bin/best-time-to-buy-and-sell-stock-ii.rs @@ -0,0 +1,24 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + assert_eq!(7, Solution::max_profit(vec![7, 1, 5, 3, 6, 4])); + assert_eq!(4, Solution::max_profit(vec![1, 2, 3, 4, 5])); +} + +struct Solution; + +impl Solution { + pub fn max_profit(prices: Vec) -> i32 { + let (mut r, mut min) = (0, prices[0]); + + for i in 1..prices.len() { + if prices[i] < prices[i - 1] { + min = prices[i]; + } else { + r += prices[i] - min; + min = prices[i]; + } + } + r + } +} diff --git a/src/bin/best-time-to-buy-and-sell-stock-with-cooldown.rs b/src/bin/best-time-to-buy-and-sell-stock-with-cooldown.rs new file mode 100644 index 00000000..3331d4ea --- /dev/null +++ b/src/bin/best-time-to-buy-and-sell-stock-with-cooldown.rs @@ -0,0 +1,40 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() { + assert_eq!(Solution::max_profit(vec![1, 2, 3, 0, 2]), 3); + assert_eq!(Solution::max_profit(vec![1]), 0); +} + +struct Solution; + +impl Solution { + /// 第i天有几种状态 + /// 1.持有股票,这时可能是持有的第i-1天的股票,或者是新买的股票 + /// 2.没有股票且处于冻结期(当天把股票卖了) + /// 3.没有股票且不处于冻结期 + /// + /// f[i][0]代表第一种情况 + /// f[i][2]代表第二种情况 + /// f[i][3]代表第三种情况 + /// + /// f[i][0] = max(f[i-1][2]-price, f[i-1][0]) + /// f[i][1] = f[i-1][0]+price + /// f[i][2] = max(f[i-1][2], f[i-1][1]) + pub fn max_profit(prices: Vec) -> i32 { + // 使用三个变量替代 + // let mut v = vec![vec![0; 3]; prices.len()]; + // v[0][0] = -prices[0]; + let (mut v0, mut v1, mut v2) = (-prices[0], 0, 0); + + for index in 1..prices.len() { + let new_v0 = v0.max(v2 - prices[index]); + let new_v1 = v0 + prices[index]; + let new_v2 = v1.max(v2); + + v0 = new_v0; + v1 = new_v1; + v2 = new_v2; + } + v0.max(v1).max(v2) + } +} diff --git a/src/bin/best-time-to-buy-and-sell-stock.rs b/src/bin/best-time-to-buy-and-sell-stock.rs new file mode 100644 index 00000000..4e03c68e --- /dev/null +++ b/src/bin/best-time-to-buy-and-sell-stock.rs @@ -0,0 +1,18 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn max_profit(prices: Vec) -> i32 { + let (mut r, mut min) = (0, prices[0]); + + for i in 1..prices.len() { + r = r.max(prices[i] - min); + min = min.min(prices[i]); + } + + r + } +} diff --git a/src/bin/biao-shi-shu-zhi-de-zi-fu-chuan-lcof.rs b/src/bin/biao-shi-shu-zhi-de-zi-fu-chuan-lcof.rs new file mode 100644 index 00000000..2f3d5ba5 --- /dev/null +++ b/src/bin/biao-shi-shu-zhi-de-zi-fu-chuan-lcof.rs @@ -0,0 +1,121 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +enum Status { + Start, + PreBlank, // 前空格 + Sign, // 符号位 + Integer, // 数字 + PointWithInteger, // 前面带数字的小数点 + PointWithoutInteger, // 前面不带数字的小数点 + IntegerAfterPoint, // 小数点后面的数字 + E, // E or e + IntegerAfterE, // E后面的数字 + SignAfterE, // E 后面的符号 + LastInteger, // 最后的数字 + PostBlank, // 后空格 + Invalid, // 无效的 +} + +impl Status { + fn new() -> Status { + Status::Start + } + + fn transform(&mut self, x: u8) { + use Status::*; + + match self { + Start => match x { + b' ' => *self = PreBlank, + b'+' | b'-' => *self = Sign, + b'0'..=b'9' => *self = Integer, + b'.' => *self = PointWithoutInteger, + _ => *self = Invalid, + }, + PreBlank => match x { + b' ' => *self = PreBlank, + b'+' | b'-' => *self = Sign, + b'0'..=b'9' => *self = Integer, + b'.' => *self = PointWithoutInteger, + _ => *self = Invalid, + }, + Sign => match x { + b'0'..=b'9' => *self = Integer, + b'.' => *self = PointWithoutInteger, + _ => *self = Invalid, + }, + Integer => match x { + b' ' => *self = PostBlank, + b'0'..=b'9' => *self = Integer, + b'.' => *self = PointWithInteger, + b'E' | b'e' => *self = E, + _ => *self = Invalid, + }, + PointWithInteger => match x { + b' ' => *self = PostBlank, + b'0'..=b'9' => *self = IntegerAfterPoint, + b'E' | b'e' => *self = E, + _ => *self = Invalid, + }, + PointWithoutInteger => match x { + b'0'..=b'9' => *self = IntegerAfterPoint, + _ => *self = Invalid, + }, + IntegerAfterPoint => match x { + b' ' => *self = PostBlank, + b'0'..=b'9' => *self = IntegerAfterPoint, + b'E' | b'e' => *self = E, + _ => *self = Invalid, + }, + E => match x { + b'0'..=b'9' => *self = IntegerAfterE, + b'+' | b'-' => *self = SignAfterE, + _ => *self = Invalid, + }, + IntegerAfterE => match x { + b' ' => *self = PostBlank, + b'0'..=b'9' => *self = IntegerAfterE, + b'+' | b'-' => *self = SignAfterE, + _ => *self = Invalid, + }, + SignAfterE => match x { + b'0'..=b'9' => *self = LastInteger, + _ => *self = Invalid, + }, + LastInteger => match x { + b' ' => *self = PostBlank, + b'0'..=b'9' => *self = LastInteger, + _ => *self = Invalid, + }, + PostBlank => match x { + b' ' => *self = PostBlank, + _ => *self = Invalid, + }, + Invalid => {} + } + } + + fn is_valid(&self) -> bool { + use Status::*; + match self { + Integer | PointWithInteger | IntegerAfterPoint | LastInteger | PostBlank + | IntegerAfterE => true, + _ => false, + } + } +} + +struct Solution; + +impl Solution { + pub fn is_number(s: String) -> bool { + let mut status = Status::new(); + for &i in s.as_bytes() { + status.transform(i); + } + + status.is_valid() + } +} diff --git a/src/bin/binary-search-tree-iterator.rs b/src/bin/binary-search-tree-iterator.rs new file mode 100644 index 00000000..cd0a3604 --- /dev/null +++ b/src/bin/binary-search-tree-iterator.rs @@ -0,0 +1,75 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +// Definition for a binary tree node. +#[derive(Debug, PartialEq, Eq)] +pub struct TreeNode { + pub val: i32, + pub left: Option>>, + pub right: Option>>, +} + +impl TreeNode { + #[inline] + pub fn new(val: i32) -> Self { + TreeNode { + val, + left: None, + right: None, + } + } +} + +use std::cell::RefCell; +use std::rc::Rc; + +/** + * Your BSTIterator object will be instantiated and called as such: + * let obj = BSTIterator::new(root); + * let ret_1: i32 = obj.next(); + * let ret_2: bool = obj.has_next(); + */ +struct BSTIterator { + stack: Vec>>>, +} + +/** + * `&self` means the method takes an immutable reference. + * If you need a mutable reference, change it to `&mut self` instead. + */ +impl BSTIterator { + fn new(root: Option>>) -> Self { + let mut s = Self { stack: vec![] }; + if root.is_some() { + s.stack.push(root); + } + s + } + + fn next(&mut self) -> i32 { + let mut node = self.stack.pop().unwrap(); + + while node.is_some() { + let s = node; + let left = s.as_ref().unwrap().borrow_mut().left.take(); + let right = s.as_ref().unwrap().borrow_mut().right.take(); + + if right.is_some() { + self.stack.push(right); + } + + self.stack.push(s); + node = left; + } + + let r = self.stack.pop().unwrap().as_ref().unwrap().borrow().val; + r + } + + fn has_next(&self) -> bool { + self.stack.len() > 0 + } +} diff --git a/src/bin/binary-search-tree-to-greater-sum-tree.rs b/src/bin/binary-search-tree-to-greater-sum-tree.rs new file mode 100644 index 00000000..9d14f868 --- /dev/null +++ b/src/bin/binary-search-tree-to-greater-sum-tree.rs @@ -0,0 +1,47 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +use std::cell::RefCell; +use std::rc::Rc; + +// Definition for a binary tree node. +#[derive(Debug, PartialEq, Eq)] +pub struct TreeNode { + pub val: i32, + pub left: Option>>, + pub right: Option>>, +} + +impl TreeNode { + #[inline] + pub fn new(val: i32) -> Self { + TreeNode { + val, + left: None, + right: None, + } + } +} + +fn main() {} + +struct Solution; + +impl Solution { + pub fn bst_to_gst(root: Option>>) -> Option>> { + let mut total = 0; + Self::dfs(root.clone(), &mut total); + root + } + + fn dfs(root: Option>>, total: &mut i32) { + if root.is_none() { + return; + } + + Self::dfs(root.as_ref().and_then(|x| x.borrow().right.clone()), total); + + root.as_ref().map(|x| x.borrow_mut().val += *total); + *total = root.as_ref().map(|x| x.borrow().val).unwrap_or(0); + Self::dfs(root.as_ref().and_then(|x| x.borrow().left.clone()), total); + } +} diff --git a/src/bin/binary-subarrays-with-sum.rs b/src/bin/binary-subarrays-with-sum.rs new file mode 100644 index 00000000..74afa1e4 --- /dev/null +++ b/src/bin/binary-subarrays-with-sum.rs @@ -0,0 +1,20 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn num_subarrays_with_sum(nums: Vec, goal: i32) -> i32 { + let mut map = std::collections::HashMap::::new(); + let mut sum = 0; + let mut result = 0; + for i in nums { + sum += i; + map.entry(sum).and_modify(|x| *x += 1).or_insert(1); + result += *map.get(&(sum - goal)).unwrap_or(&0); + } + + result + } +} diff --git a/src/bin/binary-tree-inorder-traversal.rs b/src/bin/binary-tree-inorder-traversal.rs new file mode 100644 index 00000000..b5e00789 --- /dev/null +++ b/src/bin/binary-tree-inorder-traversal.rs @@ -0,0 +1,57 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +// Definition for a binary tree node. +#[derive(Debug, PartialEq, Eq)] +pub struct TreeNode { + pub val: i32, + pub left: Option>>, + pub right: Option>>, +} + +impl TreeNode { + #[inline] + pub fn new(val: i32) -> Self { + TreeNode { + val, + left: None, + right: None, + } + } +} + +use std::cell::RefCell; +use std::rc::Rc; + +impl Solution { + pub fn inorder_traversal(root: Option>>) -> Vec { + let mut r = vec![]; + + Self::f(root, &mut r); + + r + } + + fn f(root: Option>>, r: &mut Vec) { + if root.is_none() { + return; + } + + let root = root.unwrap(); + let v = root.borrow().val; + let left = root.borrow_mut().left.take(); + if left.is_some() { + Self::f(left, r); + } + + r.push(v); + + let right = root.borrow_mut().right.take(); + if right.is_some() { + Self::f(right, r); + } + } +} diff --git a/src/bin/binary-tree-level-order-traversal-ii.rs b/src/bin/binary-tree-level-order-traversal-ii.rs new file mode 100644 index 00000000..2d038797 --- /dev/null +++ b/src/bin/binary-tree-level-order-traversal-ii.rs @@ -0,0 +1,65 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +// Definition for a binary tree node. +#[derive(Debug, PartialEq, Eq)] +pub struct TreeNode { + pub val: i32, + pub left: Option>>, + pub right: Option>>, +} + +impl TreeNode { + #[inline] + pub fn new(val: i32) -> Self { + TreeNode { + val, + left: None, + right: None, + } + } +} + +use std::cell::RefCell; +use std::rc::Rc; + +impl Solution { + pub fn level_order_bottom(root: Option>>) -> Vec> { + if let Some(r) = root { + Self::f(vec![Rc::clone(&r)]) + } else { + vec![] + } + } + + fn f(nodes: Vec>>) -> Vec> { + let mut result = vec![]; + + if nodes.len() == 0 { + return result; + } + + let mut v = vec![]; + let mut n = vec![]; + + for i in nodes.into_iter() { + v.push(i.borrow().val); + if let Some(left) = i.borrow_mut().left.take() { + n.push(left); + } + + if let Some(right) = i.borrow_mut().right.take() { + n.push(right); + } + } + + for i in Self::f(n).into_iter() { + result.push(i); + } + result.push(v); + result + } +} diff --git a/src/bin/binary-tree-level-order-traversal.rs b/src/bin/binary-tree-level-order-traversal.rs new file mode 100644 index 00000000..a944be31 --- /dev/null +++ b/src/bin/binary-tree-level-order-traversal.rs @@ -0,0 +1,64 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +// Definition for a binary tree node. +#[derive(Debug, PartialEq, Eq)] +pub struct TreeNode { + pub val: i32, + pub left: Option>>, + pub right: Option>>, +} + +impl TreeNode { + #[inline] + pub fn new(val: i32) -> Self { + TreeNode { + val, + left: None, + right: None, + } + } +} + +use std::cell::RefCell; +use std::rc::Rc; + +impl Solution { + pub fn level_order(root: Option>>) -> Vec> { + let mut v = vec![]; + + if root.is_none() { + return v; + } + + let mut queue = std::collections::VecDeque::new(); + queue.push_back(root); + + while !queue.is_empty() { + let mut l = queue.len(); + let mut v1 = Vec::with_capacity(l); + + while l > 0 { + let node = queue.pop_front().unwrap(); + let left = node.as_ref().unwrap().borrow_mut().left.take(); + let right = node.as_ref().unwrap().borrow_mut().right.take(); + if left.is_some() { + queue.push_back(left); + } + + if right.is_some() { + queue.push_back(right); + } + v1.push(node.as_ref().unwrap().borrow().val); + l -= 1; + } + + v.push(v1); + } + + v + } +} diff --git a/src/bin/binary-tree-maximum-path-sum.rs b/src/bin/binary-tree-maximum-path-sum.rs new file mode 100644 index 00000000..43eed113 --- /dev/null +++ b/src/bin/binary-tree-maximum-path-sum.rs @@ -0,0 +1,97 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +// Definition for a binary tree node. +#[derive(Debug, PartialEq, Eq)] +pub struct TreeNode { + pub val: i32, + pub left: Option>>, + pub right: Option>>, +} + +impl TreeNode { + #[inline] + pub fn new(val: i32) -> Self { + TreeNode { + val, + left: None, + right: None, + } + } +} +use std::cell::RefCell; +use std::rc::Rc; +impl Solution { + /// 递归 + pub fn max_path_sum(root: Option>>) -> i32 { + if root.is_none() { + return 0; + } + let mut max = None; + Self::max(root, &mut max); + + max.unwrap_or_default() + } + + fn max(root: Option>>, global_max: &mut Option) -> i32 { + if root.is_none() { + return 0; + } + let root = root.unwrap(); + let current = root.borrow().val; + + let left = root.borrow_mut().left.take(); + let right = root.borrow_mut().right.take(); + + let left_max = Solution::max(left, global_max); + let right_max = Solution::max(right, global_max); + + global_max.insert_if(current + left_max.max(0) + right_max.max(0), |x, y| *x > *y); + + current + left_max.max(right_max).max(0) // 当前节点的最大和 = 当前节点+子节点的最大值(且此值必须为正数) + } +} + +trait InsertIf { + fn insert_if(&mut self, value: T, f: F) + where + F: Fn(&T, &T) -> bool; +} + +impl InsertIf for Option { + fn insert_if(&mut self, value: T, f: F) + where + F: Fn(&T, &T) -> bool, + { + match self { + Some(x) => { + if f(&value, x) { + *self = Some(value); + }; + } + None => *self = Some(value), + } + } +} + +#[cfg(test)] +mod test { + use crate::InsertIf; + + #[test] + fn insert_if() { + let mut n = None; + + n.insert_if(10, |x, y| *x > *y); + assert_eq!(n, Some(10)); + + n.insert_if(11, |x, y| *x > *y); + assert_eq!(n, Some(11)); + + n.insert_if(9, |x, y| *x > *y); + assert_eq!(n, Some(11)); + } +} diff --git a/src/bin/binary-tree-paths.rs b/src/bin/binary-tree-paths.rs new file mode 100644 index 00000000..78e53652 --- /dev/null +++ b/src/bin/binary-tree-paths.rs @@ -0,0 +1,83 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +// Definition for a binary tree node. +#[derive(Debug, PartialEq, Eq)] +pub struct TreeNode { + pub val: i32, + pub left: Option>>, + pub right: Option>>, +} + +impl TreeNode { + #[inline] + pub fn new(val: i32) -> Self { + TreeNode { + val, + left: None, + right: None, + } + } +} + +use std::cell::RefCell; +use std::rc::Rc; + +impl Solution { + pub fn binary_tree_paths(root: Option>>) -> Vec { + let s = Self::f(root); + s.into_iter() + .map(|x| { + x.into_iter() + .map(|y| y.to_string()) + .collect::>() + .join("->") + }) + .collect() + } + + fn f(root: Option>>) -> Vec> { + if root.is_none() { + return vec![]; + } + + let left = root.as_ref().unwrap().borrow_mut().left.take(); + let right = root.as_ref().unwrap().borrow_mut().right.take(); + let v = root.as_ref().unwrap().borrow().val; + match (left, right) { + (Some(x), Some(y)) => { + let f = Self::f(Some(x)); + let r = Self::f(Some(y)); + f.into_iter() + .chain(r.into_iter()) + .map(|mut x| { + x.insert(0, v); + x + }) + .collect::>>() + } + (Some(x), None) => { + let f = Self::f(Some(x)); + f.into_iter() + .map(|mut x| { + x.insert(0, v); + x + }) + .collect::>>() + } + (None, Some(y)) => { + let f = Self::f(Some(y)); + f.into_iter() + .map(|mut x| { + x.insert(0, v); + x + }) + .collect::>>() + } + (None, None) => vec![vec![v]], + } + } +} diff --git a/src/bin/binary-tree-postorder-traversal.rs b/src/bin/binary-tree-postorder-traversal.rs new file mode 100644 index 00000000..e9e9a6c0 --- /dev/null +++ b/src/bin/binary-tree-postorder-traversal.rs @@ -0,0 +1,55 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +// Definition for a binary tree node. +#[derive(Debug, PartialEq, Eq)] +pub struct TreeNode { + pub val: i32, + pub left: Option>>, + pub right: Option>>, +} + +impl TreeNode { + #[inline] + pub fn new(val: i32) -> Self { + TreeNode { + val, + left: None, + right: None, + } + } +} + +use std::cell::RefCell; +use std::rc::Rc; + +impl Solution { + pub fn postorder_traversal(root: Option>>) -> Vec { + let mut v = vec![]; + let mut r = vec![]; + + let mut root = root; + + while root.is_some() { + let left = root.as_ref().unwrap().borrow_mut().left.take(); + if left.is_some() { + v.push(root); + root = left; + } else { + let right = root.as_ref().unwrap().borrow_mut().right.take(); + if right.is_none() { + r.push(root.as_ref().unwrap().borrow().val); + root = v.pop().unwrap_or(None); + } else { + v.push(root); + root = right; + } + } + } + + r + } +} diff --git a/src/bin/binary-tree-preorder-traversal.rs b/src/bin/binary-tree-preorder-traversal.rs new file mode 100644 index 00000000..9e7bdc3a --- /dev/null +++ b/src/bin/binary-tree-preorder-traversal.rs @@ -0,0 +1,54 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +// Definition for a binary tree node. +#[derive(Debug, PartialEq, Eq)] +pub struct TreeNode { + pub val: i32, + pub left: Option>>, + pub right: Option>>, +} + +impl TreeNode { + #[inline] + pub fn new(val: i32) -> Self { + TreeNode { + val, + left: None, + right: None, + } + } +} + +use std::cell::RefCell; +use std::rc::Rc; + +impl Solution { + pub fn preorder_traversal(root: Option>>) -> Vec { + let mut v: Vec>>> = vec![]; + let mut r = vec![]; + let mut root = root; + + while root.is_some() { + r.push(root.as_ref().unwrap().borrow().val); + let left = root.as_ref().unwrap().borrow_mut().left.take(); + let right = root.as_ref().unwrap().borrow_mut().right.take(); + + if left.is_some() { + root = left; + if right.is_some() { + v.push(right); + } + } else if right.is_some() { + root = right; + } else { + root = v.pop().unwrap_or(None); + } + } + + r + } +} diff --git a/src/bin/binary-tree-right-side-view.rs b/src/bin/binary-tree-right-side-view.rs new file mode 100644 index 00000000..3afc9304 --- /dev/null +++ b/src/bin/binary-tree-right-side-view.rs @@ -0,0 +1,76 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +// Definition for a binary tree node. +#[derive(Debug, PartialEq, Eq)] +pub struct TreeNode { + pub val: i32, + pub left: Option>>, + pub right: Option>>, +} + +impl TreeNode { + #[inline] + pub fn new(val: i32) -> Self { + TreeNode { + val, + left: None, + right: None, + } + } +} + +use std::cell::RefCell; +use std::rc::Rc; + +impl Solution { + pub fn right_side_view(root: Option>>) -> Vec { + let mut r = vec![]; + if root.is_none() { + return r; + } + + struct S { + level: i32, + node: Option>>, + } + let mut v = vec![S { + level: 0, + node: root, + }]; + let mut level = 0; + let mut index = 0; + + while index < v.len() { + if let Some(x) = v.get(index) { + let l = x.level; + if l == level { + r.push(x.node.as_ref().unwrap().borrow().val); + level += 1; + } + + let right = x.node.as_ref().unwrap().borrow_mut().right.take(); + let left = x.node.as_ref().unwrap().borrow_mut().left.take(); + if right.is_some() { + v.push(S { + level: l + 1, + node: right, + }); + } + + if left.is_some() { + v.push(S { + level: l + 1, + node: left, + }); + } + } + index += 1; + } + + r + } +} diff --git a/src/bin/binary-tree-zigzag-level-order-traversal.rs b/src/bin/binary-tree-zigzag-level-order-traversal.rs new file mode 100644 index 00000000..a5290707 --- /dev/null +++ b/src/bin/binary-tree-zigzag-level-order-traversal.rs @@ -0,0 +1,73 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +// Definition for a binary tree node. +#[derive(Debug, PartialEq, Eq)] +pub struct TreeNode { + pub val: i32, + pub left: Option>>, + pub right: Option>>, +} + +impl TreeNode { + #[inline] + pub fn new(val: i32) -> Self { + TreeNode { + val, + left: None, + right: None, + } + } +} + +use std::cell::RefCell; +use std::rc::Rc; + +impl Solution { + pub fn zigzag_level_order(root: Option>>) -> Vec> { + let mut v = vec![]; + if root.is_none() { + return v; + } + + let mut l = vec![root]; + let mut level = 0; + + while !l.is_empty() { + let mut r = Vec::new(); + let mut l1 = Vec::new(); + while let Some(x) = l.pop() { + r.push(x.as_ref().unwrap().borrow().val); + let left = x.as_ref().unwrap().borrow_mut().left.take(); + let right = x.as_ref().unwrap().borrow_mut().right.take(); + + if level % 2 == 0 { + if left.is_some() { + l1.push(left); + } + + if right.is_some() { + l1.push(right); + } + } else { + if right.is_some() { + l1.push(right); + } + + if left.is_some() { + l1.push(left); + } + } + } + + v.push(r); + l = l1; + level += 1; + } + + v + } +} diff --git a/src/bin/binary-watch.rs b/src/bin/binary-watch.rs new file mode 100644 index 00000000..846d92e2 --- /dev/null +++ b/src/bin/binary-watch.rs @@ -0,0 +1,27 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +use std::fmt::format; + +fn main() {} + +struct Solution; + +impl Solution { + pub fn read_binary_watch(turned_on: i32) -> Vec { + let mut result = vec![]; + for i in 0..12i8 { + let c = i.count_ones(); + if c > turned_on as u32 { + continue; + } + + for j in 0..60i8 { + if j.count_ones() == turned_on as u32 - c { + result.push(format!("{}:{:0>2}", i, j)); + } + } + } + + result + } +} diff --git a/src/bin/bisect-squares-lcci.rs b/src/bin/bisect-squares-lcci.rs new file mode 100644 index 00000000..f37fd093 --- /dev/null +++ b/src/bin/bisect-squares-lcci.rs @@ -0,0 +1,70 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + /// 直线肯定经过两个正方形的中心点,所以只能有一条 + /// 当两个正方形重合时,就有无数条, 取平行于y轴的线 + pub fn cut_squares(square1: Vec, square2: Vec) -> Vec { + // 两个正方形的中心 + let sq1_center = ( + square1[0] as f64 + (square1[2] as f64) / 2f64, + (square1[1] as f64) + (square1[2] as f64) / 2f64, + ); + let sq2_center = ( + square2[0] as f64 + (square2[2] as f64) / 2f64, + (square2[1] as f64) + (square2[2] as f64) / 2f64, + ); + + let mut result = vec![]; + // sq1_center.0 == sq2_center.1时斜率无穷大 + if sq1_center.0 == sq2_center.1 { + let x1 = sq1_center.0; + let y1 = (sq1_center.1 - square1[2] as f64 / 2f64) + .min(sq2_center.1 - square2[2] as f64 / 2f64); + let x2 = sq1_center.0; + let y2 = (sq1_center.1 + square1[2] as f64 / 2f64) + .max(sq2_center.1 + square2[2] as f64 / 2f64); + result = vec![x1, y1, x2, y2]; + } else { + // 求y = kx+b + // 求斜率k。斜率大于1/2则坐落于上下边,否则在左右边 + let k = (sq1_center.1 - sq2_center.1) / (sq1_center.0 - sq2_center.0); + // 求b + let b = sq1_center.1 - k * sq1_center.0; + + let f = |x: f64| k * x + b; + let f1 = |y: f64| (y - b) / k; + + // -1 -1f64 { + let x1 = (square1[0] as f64).min(square2[0] as f64); + let y1 = f(x1); + let x2 = ((square1[0] + square1[2]) as f64).max((square2[0] + square2[2]) as f64); + let y2 = f(x2); + result = vec![x1, y1, x2, y2]; + } else { + let y1 = (square1[1] as f64).min(square2[1] as f64); + let x1 = f1(y1); + let y2 = ((square1[1] + square1[2]) as f64).max((square2[1] + square2[2]) as f64); + let x2 = f1(y2); + result = vec![x1, y1, x2, y2]; + } + + if result[0] != result[2] { + if result[0] > result[2] { + result.swap(0, 2); + result.swap(1, 3); + } + } else { + if result[1] > result[3] { + result.swap(0, 2); + result.swap(1, 3); + } + } + } + result + } +} diff --git a/src/bin/bitwise-and-of-numbers-range.rs b/src/bin/bitwise-and-of-numbers-range.rs new file mode 100644 index 00000000..90d847d4 --- /dev/null +++ b/src/bin/bitwise-and-of-numbers-range.rs @@ -0,0 +1,19 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn range_bitwise_and(left: i32, right: i32) -> i32 { + let mut shift = 0; + let (mut m, mut n) = (left, right); + while m < n { + m >>= 1; + n >>= 1; + shift += 1; + } + + m << shift + } +} diff --git a/src/bin/boats-to-save-people.rs b/src/bin/boats-to-save-people.rs new file mode 100644 index 00000000..53472957 --- /dev/null +++ b/src/bin/boats-to-save-people.rs @@ -0,0 +1,104 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + // assert_eq!(3, Solution::num_rescue_boats(vec![3, 2, 2, 1], 3)); + // assert_eq!(1, Solution::num_rescue_boats(vec![2, 2], 6)); + // assert_eq!(2, Solution::num_rescue_boats(vec![3, 1, 7], 7)); + // assert_eq!(5, Solution::num_rescue_boats(vec![1, 3, 4, 3, 3, 5], 5)); + // assert_eq!(5, Solution::num_rescue_boats(vec![1, 3, 4, 3, 3, 5], 5)); + assert_eq!( + 53, + Solution::num_rescue_boats( + vec![ + 8, 3, 8, 3, 10, 2, 9, 1, 3, 6, 6, 4, 2, 3, 3, 8, 10, 6, 1, 8, 4, 4, 6, 3, 10, 2, 5, + 3, 6, 6, 7, 6, 5, 7, 5, 8, 8, 3, 4, 7, 2, 7, 4, 6, 2, 7, 4, 5, 5, 5, 7, 4, 7, 1, 4, + 8, 1, 7, 1, 5, 9, 1, 6, 1, 9, 7, 8, 7, 1, 1, 7, 10, 9, 7, 8, 3, 8, 3, 2, 5, 4, 2, + 5, 9, 5, 5, 8, 6, 2, 10, 5, 8, 4, 9, 4, 3, 2, 10, 6, 1 + ], + 10 + ) + ); +} + +struct Solution; + +impl Solution { + pub fn num_rescue_boats1(mut people: Vec, limit: i32) -> i32 { + people.sort(); + let (mut a, mut b, mut count) = (0usize, people.len() - 1, 0); + + while a <= b { + if a == b { + count += 1; + break; + } + + if people[a] + people[b] <= limit { + count += 1; + a += 1; + b -= 1; + } else { + count += 1; + b -= 1; + } + } + + count + } + + pub fn num_rescue_boats(people: Vec, limit: i32) -> i32 { + let mut v = vec![0; (limit + 1) as usize]; + + for i in people { + v[i as usize] += 1; + } + + let (mut a, mut b, mut count) = (0usize, v.len() - 1, 0); + + while a <= b { + if a == b { + if v[a] == 0 { + break; + } + + if a as i32 > limit / 2 { + count += v[a]; + } else { + count += v[a] / 2 + v[a] % 2; + } + break; + } + + if v[a] == 0 { + a += 1; + continue; + } + + if v[b] == 0 { + b -= 1; + continue; + } + + if a + b <= limit as usize { + if v[a] < v[b] { + count += v[a]; + v[b] -= v[a]; + a += 1; + } else if v[a] > v[b] { + count += v[b]; + v[a] -= v[b]; + b -= 1; + } else { + count += v[b]; + b -= 1; + a += 1 + } + } else { + count += v[b]; + b -= 1; + } + } + + count + } +} diff --git a/src/bin/bu-ke-pai-zhong-de-shun-zi-lcof.rs b/src/bin/bu-ke-pai-zhong-de-shun-zi-lcof.rs new file mode 100644 index 00000000..7791b860 --- /dev/null +++ b/src/bin/bu-ke-pai-zhong-de-shun-zi-lcof.rs @@ -0,0 +1,69 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn is_straight1(nums: Vec) -> bool { + let mut nums = nums; + nums.sort(); + + let mut zero_num = 0; + for i in 0..nums.len() { + if nums[i] == 0 { + zero_num += 1; + } else { + if i > 0 && nums[i - 1] != 0 { + if nums[i] - nums[i - 1] > 0 { + zero_num -= (nums[i] - nums[i - 1] - 1); + } else { + return false; + } + + if zero_num < 0 { + return false; + } + } + } + } + + true + } + + pub fn is_straight(nums: Vec) -> bool { + let mut min = std::i32::MAX; + let mut zero = 0; // 0 的数量 + let set = nums + .into_iter() + .map(|x| { + if x == 0 { + zero += 1; + } else if x < min { + min = x; + } + + x + }) + .filter(|x| *x != 0) + .collect::>(); + + if zero == 5 { + return true; + } + + for i in 0..5 { + if set.contains(&(i + min)) { + continue; + } else { + if zero > 0 { + zero -= 1; + } else { + return false; + } + } + } + + true + } +} diff --git a/src/bin/bu-yong-jia-jian-cheng-chu-zuo-jia-fa-lcof.rs b/src/bin/bu-yong-jia-jian-cheng-chu-zuo-jia-fa-lcof.rs new file mode 100644 index 00000000..d3ce935b --- /dev/null +++ b/src/bin/bu-yong-jia-jian-cheng-chu-zuo-jia-fa-lcof.rs @@ -0,0 +1,17 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn add(a: i32, b: i32) -> i32 { + let (mut a, mut b) = (a, b); + while b != 0 { + let c = a ^ b; + b = (a & b) << 1; + a = c; + } + a + } +} diff --git a/src/bin/build-an-array-with-stack-operations.rs b/src/bin/build-an-array-with-stack-operations.rs new file mode 100644 index 00000000..d583f5ad --- /dev/null +++ b/src/bin/build-an-array-with-stack-operations.rs @@ -0,0 +1,25 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn build_array(target: Vec, n: i32) -> Vec { + let mut index = 0; + let mut result = Vec::::with_capacity(target.len()); + for i in 1..=n { + result.push(String::from("Push")); + if target[index] == i { + if index == target.len() - 1 { + break; + } + index += 1; + } else { + result.push(String::from("Pop")); + } + } + + result + } +} diff --git a/src/bin/bulb-switcher.rs b/src/bin/bulb-switcher.rs new file mode 100644 index 00000000..511ee708 --- /dev/null +++ b/src/bin/bulb-switcher.rs @@ -0,0 +1,11 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn bulb_switch(n: i32) -> i32 { + (n as f64).sqrt() as i32 + } +} diff --git a/src/bin/bulls-and-cows.rs b/src/bin/bulls-and-cows.rs new file mode 100644 index 00000000..edb515f5 --- /dev/null +++ b/src/bin/bulls-and-cows.rs @@ -0,0 +1,52 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn get_hint1(secret: String, guess: String) -> String { + let (secret, guess) = (secret.as_bytes(), guess.as_bytes()); + let mut count = std::collections::HashMap::new(); + for &i in secret { + count.entry(i).and_modify(|x| *x += 1).or_insert(1); + } + + let (mut bulls, mut cows_1) = (0, 0); + + for i in 0..secret.len() { + if secret[i] == guess[i] { + bulls += 1; + } + + if let Some(x) = count.get_mut(&guess[i]) { + if *x > 0 { + *x -= 1; + cows_1 += 1; + } + } + } + + let cows = cows_1 - bulls; + + format!("{bulls}A{cows}B") + } + + pub fn get_hint(secret: String, guess: String) -> String { + let (mut c1, mut c2) = ([0; 10], [0; 10]); + let mut bulls = 0; + let (mut secret, mut guess) = (secret.as_bytes(), guess.as_bytes()); + for i in 0..secret.len() { + if secret[i] == guess[i] { + bulls += 1; + } else { + c1[(secret[i] - b'0') as usize] += 1; + c2[(guess[i] - b'0') as usize] += 1; + } + } + + let cows: i32 = (0..10).map(|x| c1[x].min(c2[x])).sum(); + + format!("{bulls}A{cows}B") + } +} diff --git a/src/bin/buy-two-chocolates.rs b/src/bin/buy-two-chocolates.rs new file mode 100644 index 00000000..73927dfe --- /dev/null +++ b/src/bin/buy-two-chocolates.rs @@ -0,0 +1,26 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn buy_choco(prices: Vec, money: i32) -> i32 { + let (mut a1, mut a2) = (prices[0].min(prices[1]), prices[1].max(prices[0])); + + for &i in prices[2..].iter() { + if i <= a1 { + a2 = a1; + a1 = i + } else if i > a1 && i < a2 { + a2 = i; + } + } + + if a1 + a2 > money { + money + } else { + money - a1 - a2 + } + } +} diff --git a/src/bin/calculate-delayed-arrival-time.rs b/src/bin/calculate-delayed-arrival-time.rs new file mode 100644 index 00000000..611b2e5f --- /dev/null +++ b/src/bin/calculate-delayed-arrival-time.rs @@ -0,0 +1,11 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn find_delayed_arrival_time(arrival_time: i32, delayed_time: i32) -> i32 { + (arrival_time + delayed_time) % 24 + } +} diff --git a/src/bin/calculate-money-in-leetcode-bank.rs b/src/bin/calculate-money-in-leetcode-bank.rs new file mode 100644 index 00000000..712a5159 --- /dev/null +++ b/src/bin/calculate-money-in-leetcode-bank.rs @@ -0,0 +1,15 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn total_money(n: i32) -> i32 { + const S: i32 = 49; + + let a = n / 7; + let b = n % 7; + ((S + a * 7) * a + (a * 2 + b + 1) * b) >> 1 + } +} diff --git a/src/bin/can-place-flowers.rs b/src/bin/can-place-flowers.rs new file mode 100644 index 00000000..f559d60f --- /dev/null +++ b/src/bin/can-place-flowers.rs @@ -0,0 +1,37 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn can_place_flowers(flowerbed: Vec, n: i32) -> bool { + let mut f = flowerbed; + let mut n = n; + + for i in 0..f.len() { + if i == 0 { + if f[i] == 0 && f.get(i + 1).unwrap_or(&0) == &0 { + f[i] = 1; + n -= 1; + } + } else if i == f.len() - 1 { + if f[i] == 0 && f.get(i - 1).unwrap_or(&0) == &0 { + f[i] = 1; + n -= 1; + } + } else { + if f[i] == 0 && f[i - 1] == 0 && f[i + 1] == 0 { + f[i] = 1; + n -= 1; + } + } + + if n <= 0 { + return true; + } + } + + false + } +} diff --git a/src/bin/capitalize-the-title.rs b/src/bin/capitalize-the-title.rs new file mode 100644 index 00000000..0866333f --- /dev/null +++ b/src/bin/capitalize-the-title.rs @@ -0,0 +1,27 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn capitalize_title(title: String) -> String { + title + .split(' ') + .map(|x| { + if x.len() <= 2 { + x.to_lowercase() + } else { + let mut s = x.to_lowercase(); + if s.as_bytes()[0] >= b'a' && s.as_bytes()[0] <= b'z' { + let w = s.as_bytes()[0] - b'a'; + unsafe { s.as_bytes_mut()[0] = b'A' + w }; + } + + s + } + }) + .collect::>() + .join(" ") + } +} diff --git a/src/bin/car-pooling.rs b/src/bin/car-pooling.rs new file mode 100644 index 00000000..482ea080 --- /dev/null +++ b/src/bin/car-pooling.rs @@ -0,0 +1,25 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn car_pooling(trips: Vec>, capacity: i32) -> bool { + let mut v = vec![0; 1002]; + + for i in trips { + v[i[1] as usize + 1] += i[0]; + v[i[2] as usize + 1] -= i[0]; + } + + for i in 1..v.len() { + v[i] = v[i] + v[i - 1]; + if v[i] > capacity { + return false; + } + } + + true + } +} diff --git a/src/bin/card-flipping-game.rs b/src/bin/card-flipping-game.rs new file mode 100644 index 00000000..2c931756 --- /dev/null +++ b/src/bin/card-flipping-game.rs @@ -0,0 +1,32 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + /// 将较大的放在前面,然后找出后面最小且不在前面的数 + pub fn flipgame(mut fronts: Vec, mut backs: Vec) -> i32 { + let mut set = std::collections::HashSet::new(); + + for i in 0..fronts.len() { + if fronts[i] == backs[i] { + set.insert(fronts[i]); + } + } + + let mut r = -1; + + for i in fronts.into_iter().chain(backs.into_iter()) { + if !set.contains(&i) { + if r == -1 { + r = i; + } else { + r = r.min(i); + } + } + } + + r.max(0) + } +} diff --git a/src/bin/categorize-box-according-to-criteria.rs b/src/bin/categorize-box-according-to-criteria.rs new file mode 100644 index 00000000..74f92599 --- /dev/null +++ b/src/bin/categorize-box-according-to-criteria.rs @@ -0,0 +1,28 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn categorize_box(length: i32, width: i32, height: i32, mass: i32) -> String { + const A: i32 = 10i32.pow(4); + const B: i64 = 10i64.pow(9); + let is_bulky = length >= A + || width >= A + || height >= A + || (length as i64 * width as i64 * height as i64) >= B; + let is_heavy = mass >= 100; + + if is_bulky && is_heavy { + "Both" + } else if is_bulky { + "Bulky" + } else if is_heavy { + "Heavy" + } else { + "Neither" + } + .into() + } +} diff --git a/src/bin/cells-with-odd-values-in-a-matrix.rs b/src/bin/cells-with-odd-values-in-a-matrix.rs new file mode 100644 index 00000000..bddc2d4a --- /dev/null +++ b/src/bin/cells-with-odd-values-in-a-matrix.rs @@ -0,0 +1,23 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn odd_cells(m: i32, n: i32, indices: Vec>) -> i32 { + let mut row = 0u64; + let mut col = 0u64; + + for e in &indices { + let ri = e[0] as u64; + let ci = e[1] as u64; + row ^= 1u64 << ri; + col ^= 1u64 << ci; + } + + let cx = row.count_ones() as i32; + let cy = col.count_ones() as i32; + cx * (n - cy) + cy * (m - cx) + } +} diff --git a/src/bin/check-if-a-string-is-an-acronym-of-words.rs b/src/bin/check-if-a-string-is-an-acronym-of-words.rs new file mode 100644 index 00000000..28503c00 --- /dev/null +++ b/src/bin/check-if-a-string-is-an-acronym-of-words.rs @@ -0,0 +1,21 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn is_acronym(words: Vec, s: String) -> bool { + if words.len() != s.len() { + return false; + } + + for i in 0..s.len() { + if words[i].as_bytes()[0] != s.as_bytes()[i] { + return false; + } + } + + true + } +} diff --git a/src/bin/check-if-a-word-occurs-as-a-prefix-of-any-word-in-a-sentence.rs b/src/bin/check-if-a-word-occurs-as-a-prefix-of-any-word-in-a-sentence.rs new file mode 100644 index 00000000..76183eaf --- /dev/null +++ b/src/bin/check-if-a-word-occurs-as-a-prefix-of-any-word-in-a-sentence.rs @@ -0,0 +1,52 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + assert_eq!( + 2, + Solution::is_prefix_of_word( + "this problem is an easy problem".to_string(), + "pro".to_string() + ) + ); + assert_eq!( + 4, + Solution::is_prefix_of_word("i use triple pillow".to_string(), "pill".to_string()) + ); + assert_eq!( + -1, + Solution::is_prefix_of_word("hello from the other side".to_string(), "they".to_string()) + ); + assert_eq!( + -1, + Solution::is_prefix_of_word("hellohello hellohellohello".to_string(), "ell".to_string()) + ); +} + +struct Solution; + +impl Solution { + pub fn is_prefix_of_word(sentence: String, search_word: String) -> i32 { + let mut index = 0; + let mut word = 0; + let mut flag = true; + for &i in sentence.as_bytes().iter() { + if flag && i == search_word.as_bytes()[index] { + if index == search_word.len() - 1 { + return word + 1 as i32; + } + index += 1; + continue; + } + + if i == b' ' { + word += 1; + flag = true; + } else { + flag = false; + } + index = 0; + } + + -1 + } +} diff --git a/src/bin/check-if-all-as-appears-before-all-bs.rs b/src/bin/check-if-all-as-appears-before-all-bs.rs new file mode 100644 index 00000000..a8ec3f91 --- /dev/null +++ b/src/bin/check-if-all-as-appears-before-all-bs.rs @@ -0,0 +1,20 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn check_string(s: String) -> bool { + let mut has_b = false; + for &i in s.as_bytes() { + if i == b'b' { + has_b = true; + } else if i == b'a' && has_b { + return false; + } + } + + true + } +} diff --git a/src/bin/check-if-all-characters-have-equal-number-of-occurrences.rs b/src/bin/check-if-all-characters-have-equal-number-of-occurrences.rs new file mode 100644 index 00000000..7a3a6174 --- /dev/null +++ b/src/bin/check-if-all-characters-have-equal-number-of-occurrences.rs @@ -0,0 +1,32 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn are_occurrences_equal(s: String) -> bool { + let mut v = [0; 26]; + for &i in s.as_bytes() { + v[(i - b'a') as usize] += 1; + } + + let mut i = 0; + + for x in v { + if x == 0 { + continue; + } + + if i != 0 { + if i != x { + return false; + } + } else { + i = x; + } + } + + true + } +} diff --git a/src/bin/check-if-array-pairs-are-divisible-by-k.rs b/src/bin/check-if-array-pairs-are-divisible-by-k.rs new file mode 100644 index 00000000..75232925 --- /dev/null +++ b/src/bin/check-if-array-pairs-are-divisible-by-k.rs @@ -0,0 +1,29 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn can_arrange(arr: Vec, k: i32) -> bool { + let mut a = vec![0; k as usize]; + for &i in arr.iter() { + let mut index = i % k; + if index < 0 { + index += k; + } + a[index as usize] += 1; + } + if a[0] % 2 != 0 { + return false; + } + + for i in 1..=a.len() / 2 { + if a[i] != a[a.len() - i] { + return false; + } + } + + true + } +} diff --git a/src/bin/check-if-grid-satisfies-conditions.rs b/src/bin/check-if-grid-satisfies-conditions.rs new file mode 100644 index 00000000..e441b621 --- /dev/null +++ b/src/bin/check-if-grid-satisfies-conditions.rs @@ -0,0 +1,27 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn satisfies_conditions(grid: Vec>) -> bool { + for i in 0..grid.len() { + for j in 0..grid[0].len() { + if let Some(Some(&x)) = grid.get(i + 1).map(|c| c.get(j)) { + if x != grid[i][j] { + return false; + } + } + + if let Some(Some(&x)) = grid.get(i).map(|c| c.get(j + 1)) { + if x == grid[i][j] { + return false; + } + } + } + } + + true + } +} diff --git a/src/bin/check-if-n-and-its-double-exist.rs b/src/bin/check-if-n-and-its-double-exist.rs index 6adab5d3..0ff2faa8 100644 --- a/src/bin/check-if-n-and-its-double-exist.rs +++ b/src/bin/check-if-n-and-its-double-exist.rs @@ -1,3 +1,5 @@ +#![allow(dead_code, unused, unused_variables)] + fn main() {} struct Solution; @@ -19,7 +21,6 @@ impl Solution { // } for &i in arr.iter() { - // 首先判断map中是否存在i的两倍的值,存在则返回true if let Some(_) = map.get(&(i * 2)) { return true; @@ -37,4 +38,4 @@ impl Solution { false } -} \ No newline at end of file +} diff --git a/src/bin/check-if-numbers-are-ascending-in-a-sentence.rs b/src/bin/check-if-numbers-are-ascending-in-a-sentence.rs new file mode 100644 index 00000000..38e3c856 --- /dev/null +++ b/src/bin/check-if-numbers-are-ascending-in-a-sentence.rs @@ -0,0 +1,20 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn are_numbers_ascending(s: String) -> bool { + let mut last = -1; + for i in s.split(' ').filter_map(|x| x.parse::().ok()) { + if i <= last { + return false; + } + + last = i; + } + + true + } +} diff --git a/src/bin/check-if-the-sentence-is-pangram.rs b/src/bin/check-if-the-sentence-is-pangram.rs new file mode 100644 index 00000000..e1ec3fd9 --- /dev/null +++ b/src/bin/check-if-the-sentence-is-pangram.rs @@ -0,0 +1,16 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn check_if_pangram(sentence: String) -> bool { + let mut v = [0u8; 26]; + for i in sentence.bytes() { + v[(i - b'a') as usize] = 1; + } + + v.iter().all(|&x| x == 1) + } +} diff --git a/src/bin/check-if-there-is-a-valid-partition-for-the-array.rs b/src/bin/check-if-there-is-a-valid-partition-for-the-array.rs new file mode 100644 index 00000000..40b4be78 --- /dev/null +++ b/src/bin/check-if-there-is-a-valid-partition-for-the-array.rs @@ -0,0 +1,24 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn valid_partition(nums: Vec) -> bool { + let mut dp = vec![false; nums.len() + 1]; + dp[0] = true; + for (i, &v) in nums.iter().enumerate() { + if (i > 0 && dp[i - 1] && v == nums[i - 1]) + || (i > 1 && dp[i - 2] && v == nums[i - 1] && v == nums[i - 2]) + || (i > 1 && dp[i - 2] && v == nums[i - 1] + 1 && v == nums[i - 2] + 2) + { + dp[i + 1] = true + } + } + + println!("{dp:?}"); + + dp[nums.len()] + } +} diff --git a/src/bin/check-if-word-is-valid-after-substitutions.rs b/src/bin/check-if-word-is-valid-after-substitutions.rs new file mode 100644 index 00000000..4a5fb392 --- /dev/null +++ b/src/bin/check-if-word-is-valid-after-substitutions.rs @@ -0,0 +1,29 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn is_valid(s: String) -> bool { + let mut stack = vec![]; + + for &i in s.as_bytes() { + match i { + b'a' | b'b' => stack.push(i), + b'c' => { + if stack.len() < 2 { + return false; + } + + if stack.pop().unwrap() != b'b' || stack.pop().unwrap() != b'a' { + return false; + } + } + _ => unreachable!(), + } + } + + stack.is_empty() + } +} diff --git a/src/bin/check-knight-tour-configuration.rs b/src/bin/check-knight-tour-configuration.rs new file mode 100644 index 00000000..f2c3a7b3 --- /dev/null +++ b/src/bin/check-knight-tour-configuration.rs @@ -0,0 +1,87 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn check_valid_grid(grid: Vec>) -> bool { + if grid[0][0] != 0 { + return false; + } + + let (mut x, mut y) = (0, 0); + let mut result = false; + for i in 1..grid.len() * grid.len() { + let (r1, x1, y1) = Self::check(&grid[..], x, y, i as i32); + if !r1 { + return false; + } + + x = x1; + y = y1; + } + + true + } + + pub fn check(grid: &[Vec], x: usize, y: usize, expect: i32) -> (bool, usize, usize) { + if x > 1 { + if y > 0 { + if grid[x - 2][y - 1] == expect { + return (true, x - 2, y - 1); + } + } + + if y < grid.len() - 1 { + if grid[x - 2][y + 1] == expect { + return (true, x - 2, y + 1); + } + } + } + + if x < grid.len() - 2 { + if y > 0 { + if grid[x + 2][y - 1] == expect { + return (true, x + 2, y - 1); + } + } + + if y < grid.len() - 1 { + if grid[x + 2][y + 1] == expect { + return (true, x + 2, y + 1); + } + } + } + + if y > 1 { + if x > 0 { + if grid[x - 1][y - 2] == expect { + return (true, x - 1, y - 2); + } + } + + if x < grid.len() - 1 { + if grid[x + 1][y - 2] == expect { + return (true, x + 1, y - 2); + } + } + } + + if y < grid.len() - 2 { + if x > 0 { + if grid[x - 1][y + 2] == expect { + return (true, x - 1, y + 2); + } + } + + if x < grid.len() - 1 { + if grid[x + 1][y + 2] == expect { + return (true, x + 1, y + 2); + } + } + } + + (false, 0, 0) + } +} diff --git a/src/bin/check-whether-two-strings-are-almost-equivalent.rs b/src/bin/check-whether-two-strings-are-almost-equivalent.rs new file mode 100644 index 00000000..4485ff97 --- /dev/null +++ b/src/bin/check-whether-two-strings-are-almost-equivalent.rs @@ -0,0 +1,23 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +use tokio_stream::StreamExt; + +fn main() {} + +struct Solution; + +impl Solution { + pub fn check_almost_equivalent(word1: String, word2: String) -> bool { + let mut v = vec![0i32; 26]; + + for &i in word1.as_bytes() { + v[(i - b'a') as usize] += 1; + } + + for &i in word2.as_bytes() { + v[(i - b'a') as usize] -= 1; + } + + v.into_iter().all(|x| x.abs() <= 3) + } +} diff --git a/src/bin/chou-shu-lcof.rs b/src/bin/chou-shu-lcof.rs new file mode 100644 index 00000000..c4d272a9 --- /dev/null +++ b/src/bin/chou-shu-lcof.rs @@ -0,0 +1,31 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn nth_ugly_number(n: i32) -> i32 { + let mut dp = vec![0; n as usize + 1]; + dp[1] = 1; + let (mut dpa, mut dpb, mut dpc) = (1, 1, 1); + for i in 2..=n as usize { + let next = (dp[dpa] * 2).min(dp[dpb] * 3).min(dp[dpc] * 5); + dp[i] = next; + + if next == dp[dpa] * 2 { + dpa += 1; + } + + if next == dp[dpb] * 3 { + dpb += 1; + } + + if next == dp[dpc] * 5 { + dpc += 1; + } + } + + dp[n as usize] + } +} diff --git a/src/bin/chuan-di-xin-xi.rs b/src/bin/chuan-di-xin-xi.rs index 361df50a..26fb8a94 100644 --- a/src/bin/chuan-di-xin-xi.rs +++ b/src/bin/chuan-di-xin-xi.rs @@ -1,5 +1,15 @@ +#![allow(dead_code, unused, unused_variables)] + fn main() { - let relation = vec![vec![0,2],vec![2,1],vec![3,4],vec![2,3],vec![1,4],vec![2,0],vec![0,4]]; + let relation = vec![ + vec![0, 2], + vec![2, 1], + vec![3, 4], + vec![2, 3], + vec![1, 4], + vec![2, 0], + vec![0, 4], + ]; assert_eq!(3, Solution::num_ways(5, relation, 3)); } @@ -11,7 +21,9 @@ impl Solution { let mut m: HashMap> = std::collections::HashMap::with_capacity(n as usize); for i in relation.iter() { - m.entry(i[0]).and_modify(|e| e.push(i[1])).or_insert(vec![i[1]]); + m.entry(i[0]) + .and_modify(|e| e.push(i[1])) + .or_insert(vec![i[1]]); } let mut num = 0; // 方案数 @@ -20,7 +32,6 @@ impl Solution { for _ in 0..k { let mut p = Vec::new(); for i in people.into_iter() { - if let Some(s1) = m.get_mut(&i) { p.append(&mut s1.clone()) } @@ -29,7 +40,7 @@ impl Solution { } for i in people.iter() { - if *i == n-1 { + if *i == n - 1 { num += 1; } } diff --git a/src/bin/circle-and-rectangle-overlapping.rs b/src/bin/circle-and-rectangle-overlapping.rs new file mode 100644 index 00000000..2d2d317a --- /dev/null +++ b/src/bin/circle-and-rectangle-overlapping.rs @@ -0,0 +1,29 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + /// 找到矩形边上的点到圆心的距离是否小于等于圆的半径 + pub fn check_overlap( + radius: i32, + x_center: i32, + y_center: i32, + x1: i32, + y1: i32, + x2: i32, + y2: i32, + ) -> bool { + let mut d = 0; + if x_center < x1 || x_center > x2 { + d += (x1 - x_center).pow(2).min((x2 - x_center).pow(2)); + } + + if y_center < y1 || y_center > y2 { + d += (y1 - y_center).pow(2).min((y2 - y_center).pow(2)); + } + + d <= radius.pow(2) + } +} diff --git a/src/bin/circular-sentence.rs b/src/bin/circular-sentence.rs new file mode 100644 index 00000000..8d7d21b9 --- /dev/null +++ b/src/bin/circular-sentence.rs @@ -0,0 +1,32 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn is_circular_sentence(sentence: String) -> bool { + let bytes = sentence.as_bytes(); + if bytes[0] != bytes[bytes.len() - 1] { + return false; + } + + let (mut current, mut flag) = (bytes[0], false); + for i in sentence.bytes() { + if i == b' ' { + flag = true; + } else { + if flag { + if i != current { + return false; + } + flag = false; + } + + current = i; + } + } + + true + } +} diff --git a/src/bin/climbing-stairs.rs b/src/bin/climbing-stairs.rs new file mode 100644 index 00000000..6bb8a202 --- /dev/null +++ b/src/bin/climbing-stairs.rs @@ -0,0 +1,22 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn climb_stairs(n: i32) -> i32 { + if n == 1 || n == 2 { + return n; + } + + let (mut a, mut b) = (1, 2); + + for _i in 3..=n { + let a1 = a; + a = b; + b = a1 + b; + } + b + } +} diff --git a/src/bin/closest-nodes-queries-in-a-binary-search-tree.rs b/src/bin/closest-nodes-queries-in-a-binary-search-tree.rs new file mode 100644 index 00000000..3d209ca7 --- /dev/null +++ b/src/bin/closest-nodes-queries-in-a-binary-search-tree.rs @@ -0,0 +1,60 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +use std::cell::RefCell; +use std::rc::Rc; + +// Definition for a binary tree node. +#[derive(Debug, PartialEq, Eq)] +pub struct TreeNode { + pub val: i32, + pub left: Option>>, + pub right: Option>>, +} + +impl TreeNode { + #[inline] + pub fn new(val: i32) -> Self { + TreeNode { + val, + left: None, + right: None, + } + } +} + +fn main() {} + +struct Solution; + +impl Solution { + pub fn closest_nodes(root: Option>>, queries: Vec) -> Vec> { + let mut items = vec![]; + Self::dfs(root, &mut items); + + let mut result = vec![]; + for q in queries { + let j = items.partition_point(|x| *x < q); + let mx = if j < items.len() { items[j] } else { -1 }; + let mn = if j < items.len() && items[j] == q { + q + } else if j > 0 { + items[j - 1] + } else { + -1 + }; + result.push(vec![mn, mx]); + } + + result + } + + fn dfs(root: Option>>, items: &mut Vec) { + if root.is_none() { + return; + } + let root = root.unwrap(); + Self::dfs(root.borrow_mut().left.take(), items); + items.push(root.borrow().val); + Self::dfs(root.borrow_mut().right.take(), items); + } +} diff --git a/src/bin/coin-change-ii.rs b/src/bin/coin-change-ii.rs new file mode 100644 index 00000000..16bc73fb --- /dev/null +++ b/src/bin/coin-change-ii.rs @@ -0,0 +1,20 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn change(amount: i32, coins: Vec) -> i32 { + let mut r = vec![0; amount as usize + 1]; + r[0] = 1; + + for coin in coins { + for i in coin..=amount { + r[i as usize] += r[(i - coin) as usize]; + } + } + + r[amount as usize] + } +} diff --git a/src/bin/coin-change.rs b/src/bin/coin-change.rs new file mode 100644 index 00000000..f3974ba5 --- /dev/null +++ b/src/bin/coin-change.rs @@ -0,0 +1,53 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + println!("{}", Solution::coin_change(vec![1, 2, 5], 11)); + println!("{}", Solution::coin_change(vec![1], 1)); + println!("{}", Solution::coin_change(vec![1, 2, 5], 100)); +} + +struct Solution; + +impl Solution { + pub fn coin_change(coins: Vec, amount: i32) -> i32 { + if amount == 0 { + return 0; + } + + let mut h = std::collections::HashMap::new(); + + Self::f(&coins[..], &mut h, amount) + } + + fn f(coins: &[i32], h: &mut std::collections::HashMap, amount: i32) -> i32 { + let mut num = -1; + + for &i in coins { + if i > amount { + continue; + } else if i == amount { + return 1; + } + + let x = if let Some(x) = h.get(&(amount - i)) { + *x + } else { + Self::f(coins, h, amount - i) + }; + + if x == -1 { + continue; + } + + if num == -1 { + num = x + 1; + } else { + num = num.min(x + 1); + } + } + + h.insert(amount, num); + + num + } +} diff --git a/src/bin/combination-sum-iii.rs b/src/bin/combination-sum-iii.rs new file mode 100644 index 00000000..b7b4c4c3 --- /dev/null +++ b/src/bin/combination-sum-iii.rs @@ -0,0 +1,46 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + println!("{:?}", Solution::combination_sum3(3, 9)); + println!("{:?}", Solution::combination_sum3(3, 7)); +} + +struct Solution; + +impl Solution { + pub fn combination_sum3(k: i32, n: i32) -> Vec> { + let mut v = vec![]; + + for i in 1..9 { + v.append(Self::func(i, k, n).as_mut()); + } + + v + } + + fn func(start: i32, k: i32, n: i32) -> Vec> { + let mut v = vec![]; + + if k <= 0 || n <= 0 { + return v; + } + + if k == 1 { + if n == start { + v.push(vec![start]); + } + return v; + } + + for i in start + 1..=9 { + for mut j in Self::func(i, k - 1, n - start) { + let mut v1 = Vec::with_capacity(k as usize); + v1.push(start); + v1.append(j.as_mut()); + v.push(v1); + } + } + + v + } +} diff --git a/src/bin/combination-sum-iv.rs b/src/bin/combination-sum-iv.rs new file mode 100644 index 00000000..f1f85b84 --- /dev/null +++ b/src/bin/combination-sum-iv.rs @@ -0,0 +1,32 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn combination_sum4(nums: Vec, target: i32) -> i32 { + Self::dp(&mut std::collections::HashMap::new(), &nums, target) + } + + pub fn dp(hash: &mut std::collections::HashMap, nums: &[i32], target: i32) -> i32 { + if let Some(x) = hash.get(&target) { + return *x; + } + + if target == 0 { + return 1; + } else if target < 0 { + return 0; + } + + let mut result = 0; + for &i in nums { + result += Self::dp(hash, nums, target - i); + } + + hash.insert(target, result); + + result + } +} diff --git a/src/bin/combination-sum.rs b/src/bin/combination-sum.rs new file mode 100644 index 00000000..fc53fa78 --- /dev/null +++ b/src/bin/combination-sum.rs @@ -0,0 +1,41 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn combination_sum(candidates: Vec, target: i32) -> Vec> { + let mut candidates = candidates; + candidates.sort(); + Self::calc(&candidates, target) + } + + fn calc(candidates: &Vec, target: i32) -> Vec> { + let mut r = vec![]; + + for &i in candidates.iter() { + if i > target { + break; + } + + let mut v = vec![]; + if i == target { + v.push(i); + r.push(v); + } else if i < target { + let x = Self::calc(&candidates, target - i); + for mut m in x { + if !m.is_empty() { + if i >= *m.last().unwrap() { + // 递增排列,用于去重复 + m.push(i); + r.push(m); + } + } + } + } + } + r + } +} diff --git a/src/bin/combinations.rs b/src/bin/combinations.rs new file mode 100644 index 00000000..6a36b1bc --- /dev/null +++ b/src/bin/combinations.rs @@ -0,0 +1,29 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + println!("{:?}", Solution::combine(4, 2)); +} + +struct Solution; + +impl Solution { + pub fn combine(n: i32, k: i32) -> Vec> { + Self::get(1, n, k) + } + + fn get(start: i32, end: i32, k: i32) -> Vec> { + let mut result = Vec::new(); + + for i in (start..=end).rev() { + if k != 1 { + for mut j in Self::get(start, i - 1, k - 1) { + j.push(i); + result.push(j); + } + } else { + result.push(vec![i]); + } + } + result + } +} diff --git a/src/bin/compare-strings-by-frequency-of-the-smallest-character.rs b/src/bin/compare-strings-by-frequency-of-the-smallest-character.rs new file mode 100644 index 00000000..fb0884cb --- /dev/null +++ b/src/bin/compare-strings-by-frequency-of-the-smallest-character.rs @@ -0,0 +1,51 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn num_smaller_by_frequency(queries: Vec, words: Vec) -> Vec { + let s1 = queries + .into_iter() + .map(|x| Self::count(x.as_bytes())) + .collect::>(); + + let s2 = words + .into_iter() + .map(|x| Self::count(x.as_bytes())) + .collect::>(); + + let mut result = vec![]; + + for i in s1 { + let mut count = 0; + + for j in s2.iter() { + if i < *j { + count += 1; + } + } + + result.push(count); + } + + result + } + + fn count(s: &[u8]) -> i32 { + let mut count = 1; + let mut min = s[0]; + + for &i in &s[1..] { + if i < min { + min = i; + count = 1; + } else if i == min { + count += 1; + } + } + + count + } +} diff --git a/src/bin/compare-version-numbers.rs b/src/bin/compare-version-numbers.rs new file mode 100644 index 00000000..f3e0c014 --- /dev/null +++ b/src/bin/compare-version-numbers.rs @@ -0,0 +1,43 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn compare_version(version1: String, version2: String) -> i32 { + let (mut s1, mut s2) = (0, 0); + let (v1, v2) = (version1.as_bytes(), version2.as_bytes()); + + loop { + let (mut r1, mut r2) = (0, 0); + for i in s1..v1.len() { + s1 = i + 1; + if v1[i] == b'.' { + break; + } else { + r1 = r1 * 10 + v1[i] - b'0'; + } + } + + for i in s2..v2.len() { + s2 = i + 1; + if v2[i] == b'.' { + break; + } else { + r2 = r2 * 10 + v2[i] - b'0'; + } + } + + if r1 > r2 { + return 1; + } else if r1 < r2 { + return -1; + } + + if s1 == v1.len() && s2 == v2.len() { + return 0; + } + } + } +} diff --git a/src/bin/complement-of-base-10-integer.rs b/src/bin/complement-of-base-10-integer.rs new file mode 100644 index 00000000..de84fa38 --- /dev/null +++ b/src/bin/complement-of-base-10-integer.rs @@ -0,0 +1,15 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn bitwise_complement(n: i32) -> i32 { + let mut ones = 1; + while ones < n { + ones = (ones << 1) + 1 + } + ones ^ n + } +} diff --git a/src/bin/cong-shang-dao-xia-da-yin-er-cha-shu-ii-lcof.rs b/src/bin/cong-shang-dao-xia-da-yin-er-cha-shu-ii-lcof.rs new file mode 100644 index 00000000..5d9d5824 --- /dev/null +++ b/src/bin/cong-shang-dao-xia-da-yin-er-cha-shu-ii-lcof.rs @@ -0,0 +1,64 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +// Definition for a binary tree node. +#[derive(Debug, PartialEq, Eq)] +pub struct TreeNode { + pub val: i32, + pub left: Option>>, + pub right: Option>>, +} + +impl TreeNode { + #[inline] + pub fn new(val: i32) -> Self { + TreeNode { + val, + left: None, + right: None, + } + } +} +use std::cell::RefCell; +use std::rc::Rc; +impl Solution { + pub fn level_order(root: Option>>) -> Vec> { + if root.is_none() { + return vec![]; + } + + let mut data = vec![]; + let mut stack = vec![root]; + + while !stack.is_empty() { + let mut r = vec![]; + let mut new_stack = vec![]; + let mut index = 0; + + while index < stack.len() { + if let Some(x) = stack[index].clone() { + r.push(x.borrow().val); + + let left = x.borrow_mut().left.take(); + if left.is_some() { + new_stack.push(left); + } + + let right = x.borrow_mut().right.take(); + if right.is_some() { + new_stack.push(right); + } + } + index += 1; + } + + stack = new_stack; + data.push(r); + } + + data + } +} diff --git a/src/bin/cong-shang-dao-xia-da-yin-er-cha-shu-iii-lcof.rs b/src/bin/cong-shang-dao-xia-da-yin-er-cha-shu-iii-lcof.rs new file mode 100644 index 00000000..44a52bb8 --- /dev/null +++ b/src/bin/cong-shang-dao-xia-da-yin-er-cha-shu-iii-lcof.rs @@ -0,0 +1,60 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +// Definition for a binary tree node. +#[derive(Debug, PartialEq, Eq)] +pub struct TreeNode { + pub val: i32, + pub left: Option>>, + pub right: Option>>, +} + +impl TreeNode { + #[inline] + pub fn new(val: i32) -> Self { + TreeNode { + val, + left: None, + right: None, + } + } +} +use std::cell::RefCell; +use std::rc::Rc; +impl Solution { + pub fn level_order(root: Option>>) -> Vec> { + if root.is_none() { + return vec![]; + } + + let mut stack = vec![root.unwrap()]; + let mut data = vec![]; + let mut level = 1; + + while !stack.is_empty() { + let mut new_stack = vec![]; + let mut d = vec![]; + + while let Some(x) = stack.pop() { + d.push(x.borrow().val); + if level % 2 == 1 { + x.borrow_mut().left.take().map(|x| new_stack.push(x)); + x.borrow_mut().right.take().map(|x| new_stack.push(x)); + } else { + x.borrow_mut().right.take().map(|x| new_stack.push(x)); + x.borrow_mut().left.take().map(|x| new_stack.push(x)); + } + } + + level += 1; + + data.push(d); + stack = new_stack; + } + + data + } +} diff --git a/src/bin/cong-shang-dao-xia-da-yin-er-cha-shu-lcof.rs b/src/bin/cong-shang-dao-xia-da-yin-er-cha-shu-lcof.rs new file mode 100644 index 00000000..28268fd6 --- /dev/null +++ b/src/bin/cong-shang-dao-xia-da-yin-er-cha-shu-lcof.rs @@ -0,0 +1,47 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +// Definition for a binary tree node. +#[derive(Debug, PartialEq, Eq)] +pub struct TreeNode { + pub val: i32, + pub left: Option>>, + pub right: Option>>, +} + +impl TreeNode { + #[inline] + pub fn new(val: i32) -> Self { + TreeNode { + val, + left: None, + right: None, + } + } +} +use std::cell::RefCell; +use std::rc::Rc; +impl Solution { + pub fn level_order(root: Option>>) -> Vec { + let mut v = vec![]; + let mut stack = vec![root]; + let mut index = 0; + + while index < stack.len() { + if let Some(ref x) = stack[index].clone() { + v.push(x.borrow().val); + + stack.push(x.borrow_mut().left.take()); + + stack.push(x.borrow_mut().right.take()); + } + + index += 1; + } + + v + } +} diff --git a/src/bin/cong-wei-dao-tou-da-yin-lian-biao-lcof.rs b/src/bin/cong-wei-dao-tou-da-yin-lian-biao-lcof.rs new file mode 100644 index 00000000..ca794c45 --- /dev/null +++ b/src/bin/cong-wei-dao-tou-da-yin-lian-biao-lcof.rs @@ -0,0 +1,36 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +// Definition for singly-linked list. +#[derive(PartialEq, Eq, Clone, Debug)] +pub struct ListNode { + pub val: i32, + pub next: Option>, +} + +impl ListNode { + #[inline] + fn new(val: i32) -> Self { + ListNode { next: None, val } + } +} + +impl Solution { + pub fn reverse_print(head: Option>) -> Vec { + let mut result = vec![]; + let mut head = head; + + while head.is_some() { + let h = head.unwrap(); + result.push(h.val); + head = h.next; + } + + result.reverse(); + + result + } +} diff --git a/src/bin/construct-binary-search-tree-from-preorder-traversal.rs b/src/bin/construct-binary-search-tree-from-preorder-traversal.rs index c6ec4328..5c550eae 100644 --- a/src/bin/construct-binary-search-tree-from-preorder-traversal.rs +++ b/src/bin/construct-binary-search-tree-from-preorder-traversal.rs @@ -1,3 +1,5 @@ +#![allow(dead_code, unused, unused_variables)] + fn main() { let v = vec![1, 23, 2, 25, 12, 6]; Solution::bst_from_preorder(v); @@ -22,10 +24,9 @@ impl TreeNode { } } +use std::cell::RefCell; use std::rc::Rc; -use std::cell::RefCell; -use std::ops::Deref; struct Solution; @@ -42,16 +43,20 @@ impl Solution { if n.borrow().val > i { if let Some(s) = &n.clone().borrow().left { n = Rc::clone(s); - continue + continue; } - n.borrow_mut().left.replace(Rc::new(RefCell::new(TreeNode::new(i)))); + n.borrow_mut() + .left + .replace(Rc::new(RefCell::new(TreeNode::new(i)))); break; } else { if let Some(s) = n.clone().borrow().right.as_ref() { n = Rc::clone(s); continue; } - n.borrow_mut().right.replace(Rc::new(RefCell::new(TreeNode::new(i)))); + n.borrow_mut() + .right + .replace(Rc::new(RefCell::new(TreeNode::new(i)))); break; } } diff --git a/src/bin/construct-binary-tree-from-inorder-and-postorder-traversal.rs b/src/bin/construct-binary-tree-from-inorder-and-postorder-traversal.rs new file mode 100644 index 00000000..598edecb --- /dev/null +++ b/src/bin/construct-binary-tree-from-inorder-and-postorder-traversal.rs @@ -0,0 +1,53 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +// Definition for a binary tree node. +#[derive(Debug, PartialEq, Eq)] +pub struct TreeNode { + pub val: i32, + pub left: Option>>, + pub right: Option>>, +} + +impl TreeNode { + #[inline] + pub fn new(val: i32) -> Self { + TreeNode { + val, + left: None, + right: None, + } + } +} + +use std::cell::RefCell; +use std::rc::Rc; + +impl Solution { + pub fn build_tree(inorder: Vec, postorder: Vec) -> Option>> { + Self::build(&inorder[..], &postorder[..]) + } + + fn build(inorder: &[i32], postorder: &[i32]) -> Option>> { + if postorder.len() == 0 { + return None; + } + + let mut root = TreeNode::new(postorder[postorder.len() - 1]); + let mut s = postorder.len() - 1; + for (i, &v) in inorder.iter().enumerate() { + if v == postorder[postorder.len() - 1] { + s = i; + break; + } + } + + root.left = Self::build(&inorder[..s], &postorder[..s]); + root.right = Self::build(&inorder[s + 1..], &postorder[s..postorder.len() - 1]); + + Some(Rc::new(RefCell::new(root))) + } +} diff --git a/src/bin/construct-binary-tree-from-preorder-and-inorder-traversal.rs b/src/bin/construct-binary-tree-from-preorder-and-inorder-traversal.rs new file mode 100644 index 00000000..dbc49560 --- /dev/null +++ b/src/bin/construct-binary-tree-from-preorder-and-inorder-traversal.rs @@ -0,0 +1,54 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +// Definition for a binary tree node. +#[derive(Debug, PartialEq, Eq)] +pub struct TreeNode { + pub val: i32, + pub left: Option>>, + pub right: Option>>, +} + +impl TreeNode { + #[inline] + pub fn new(val: i32) -> Self { + TreeNode { + val, + left: None, + right: None, + } + } +} + +use std::cell::RefCell; +use std::rc::Rc; + +impl Solution { + pub fn build_tree(preorder: Vec, inorder: Vec) -> Option>> { + Self::build(&preorder[..], &inorder[..]) + } + + fn build(preorder: &[i32], inorder: &[i32]) -> Option>> { + if preorder.len() == 0 { + return None; + } + + let mut root = TreeNode::new(preorder[0]); + + let mut s = 0; + for (i, &v) in inorder.iter().enumerate() { + if v == preorder[0] { + s = i; + break; + } + } + + root.left = Self::build(&preorder[1..1 + s], &inorder[..s]); + root.right = Self::build(&preorder[1 + s..], &inorder[1 + s..]); + + Some(Rc::new(RefCell::new(root))) + } +} diff --git a/src/bin/construct-binary-tree-from-preorder-and-postorder-traversal.rs b/src/bin/construct-binary-tree-from-preorder-and-postorder-traversal.rs new file mode 100644 index 00000000..2cbbd280 --- /dev/null +++ b/src/bin/construct-binary-tree-from-preorder-and-postorder-traversal.rs @@ -0,0 +1,80 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + Solution::construct_from_pre_post(vec![1, 2, 4, 5, 3, 6, 7], vec![4, 5, 2, 6, 7, 3, 1]); +} + +struct Solution; + +// Definition for a binary tree node. +#[derive(Debug, PartialEq, Eq)] +pub struct TreeNode { + pub val: i32, + pub left: Option>>, + pub right: Option>>, +} + +impl TreeNode { + #[inline] + pub fn new(val: i32) -> Self { + TreeNode { + val, + left: None, + right: None, + } + } +} + +use std::cell::RefCell; +use std::rc::Rc; + +impl Solution { + pub fn construct_from_pre_post(pre: Vec, post: Vec) -> Option>> { + let mut v: Vec>> = vec![]; + + let (mut pre_index, mut post_index) = (0usize, 0usize); + + loop { + if post_index == post.len() { + break; + } + + if v.last().is_some() && v.last().unwrap().borrow().val == post[post_index] { + if let Some(n1) = v.pop() { + if let Some(n2) = v.pop() { + if n2.as_ref().borrow().left.is_none() { + n2.as_ref().borrow_mut().left = Some(n1); + } else { + n2.as_ref().borrow_mut().right = Some(n1); + } + + v.push(n2); + } else { + v.push(n1); + } + post_index += 1; + } + } else if pre[pre_index] == post[post_index] { + let n = Some(Rc::new(RefCell::new(TreeNode::new(post[post_index])))); + if let Some(node) = v.pop() { + if node.as_ref().borrow().left.is_none() { + node.as_ref().borrow_mut().left = n; + } else { + node.as_ref().borrow_mut().right = n; + } + + v.push(node); + } else { + v.push(Rc::new(RefCell::new(TreeNode::new(pre[pre_index])))); + } + post_index += 1; + pre_index += 1; + } else { + v.push(Rc::new(RefCell::new(TreeNode::new(pre[pre_index])))); + pre_index += 1; + } + } + + v.pop() + } +} diff --git a/src/bin/construct-string-with-repeat-limit.rs b/src/bin/construct-string-with-repeat-limit.rs new file mode 100644 index 00000000..f463b4fa --- /dev/null +++ b/src/bin/construct-string-with-repeat-limit.rs @@ -0,0 +1,55 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn repeat_limited_string(s: String, repeat_limit: i32) -> String { + let mut count = [0; 26]; + + for i in s.as_bytes() { + count[(*i - b'a') as usize] += 1; + } + + let mut result = vec![]; + 'L: loop { + for i in (0..26).rev() { + if count[i] == 0 { + if i == 0 { + break 'L; + } + continue; + } + + if count[i] <= repeat_limit { + for j in 0..count[i] { + result.push(i as u8 + b'a'); + } + count[i] = 0; + continue 'L; + } else { + for j in 0..repeat_limit { + result.push(i as u8 + b'a'); + } + count[i] -= repeat_limit; + let mut flag = false; + for j in (0..i).rev() { + if count[j] != 0 { + result.push(j as u8 + b'a'); + count[j] -= 1; + flag = true; + continue 'L; + } + } + + if !flag { + break 'L; + } + } + } + } + + unsafe { String::from_utf8_unchecked(result) } + } +} diff --git a/src/bin/container-with-most-water.rs b/src/bin/container-with-most-water.rs new file mode 100644 index 00000000..029da294 --- /dev/null +++ b/src/bin/container-with-most-water.rs @@ -0,0 +1,33 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + assert_eq!(49, Solution::max_area(vec![1, 8, 6, 2, 5, 4, 8, 3, 7])); + assert_eq!(16, Solution::max_area(vec![4, 3, 2, 1, 4])); + assert_eq!(2, Solution::max_area(vec![1, 2, 1])); +} + +struct Solution; + +impl Solution { + /// 双指针,第一个指针指向开始的元素,第二个指针指向最后一个元素,则此时的面积为: + /// 第一个元素和最后一个元素的最小值 * 下标之差 + /// 然后比较两个元素,第一个元素小,则第一个指针+1 + /// 第二个元素小,则第二个指针-1 + /// 然后再计算此时的面积,取与存在的面积的最大值 + /// 依次计算,直到两个指针相等为止 + pub fn max_area(height: Vec) -> i32 { + let (mut pointer1, mut pointer2) = (0usize, height.len() - 1); + let mut area = (pointer2 - pointer1) as i32 * height[pointer2].min(height[pointer1]); + while pointer1 != pointer2 { + if height[pointer1] <= height[pointer2] { + pointer1 += 1; + } else { + pointer2 -= 1; + } + + area = area.max((pointer2 - pointer1) as i32 * height[pointer2].min(height[pointer1])); + } + + area + } +} diff --git a/src/bin/contains-duplicate-ii.rs b/src/bin/contains-duplicate-ii.rs new file mode 100644 index 00000000..830918fd --- /dev/null +++ b/src/bin/contains-duplicate-ii.rs @@ -0,0 +1,22 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn contains_nearby_duplicate(nums: Vec, k: i32) -> bool { + let mut hash = std::collections::HashMap::new(); + for (i, v) in nums.into_iter().enumerate() { + if let Some(i1) = hash.get(&v) { + if i - i1 <= k as usize { + return true; + } + } + + hash.insert(v, i); + } + + false + } +} diff --git a/src/bin/contains-duplicate.rs b/src/bin/contains-duplicate.rs new file mode 100644 index 00000000..e9844409 --- /dev/null +++ b/src/bin/contains-duplicate.rs @@ -0,0 +1,21 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn contains_duplicate(nums: Vec) -> bool { + let mut hash = std::collections::HashSet::new(); + + for i in nums.into_iter() { + if hash.contains(&i) { + return true; + } + + hash.insert(i); + } + + false + } +} diff --git a/src/bin/convert-binary-number-in-a-linked-list-to-integer.rs b/src/bin/convert-binary-number-in-a-linked-list-to-integer.rs new file mode 100644 index 00000000..de813ef5 --- /dev/null +++ b/src/bin/convert-binary-number-in-a-linked-list-to-integer.rs @@ -0,0 +1,38 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +// Definition for singly-linked list. +#[derive(PartialEq, Eq, Clone, Debug)] +pub struct ListNode { + pub val: i32, + pub next: Option>, +} + +impl ListNode { + #[inline] + fn new(val: i32) -> Self { + ListNode { next: None, val } + } +} + +impl Solution { + pub fn get_decimal_value(head: Option>) -> i32 { + let mut v = vec![]; + let mut root = head; + while root.is_some() { + v.push(root.as_ref().unwrap().val); + root = root.unwrap().next; + } + + let (mut num, mut a) = (0, 1); + for i in (0..v.len()).rev().into_iter() { + num += a * v[i]; + a *= 2; + } + + num + } +} diff --git a/src/bin/convert-bst-to-greater-tree.rs b/src/bin/convert-bst-to-greater-tree.rs new file mode 100644 index 00000000..75e993ca --- /dev/null +++ b/src/bin/convert-bst-to-greater-tree.rs @@ -0,0 +1,99 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +// Definition for a binary tree node. +#[derive(Debug, PartialEq, Eq)] +pub struct TreeNode { + pub val: i32, + pub left: Option>>, + pub right: Option>>, +} + +impl TreeNode { + #[inline] + pub fn new(val: i32) -> Self { + TreeNode { + val, + left: None, + right: None, + } + } +} +use std::cell::RefCell; +use std::rc::Rc; + +impl Solution { + /// 先求出总和 + /// 因为中序遍历是按大小遍历的,所以记录下前缀和,则当前节点的 + pub fn convert_bst1(root: Option>>) -> Option>> { + if root.is_none() { + return None; + } + let mut total = 0; + let mut stack = vec![root.clone()]; + while !stack.is_empty() { + let s = stack.pop().unwrap(); + total += s.clone().unwrap().borrow().val; + if s.clone().unwrap().borrow().left.is_some() { + stack.push(s.clone().unwrap().borrow().left.clone()); + } + + if s.clone().unwrap().borrow().right.is_some() { + stack.push(s.clone().unwrap().borrow().right.clone()); + } + } + + Self::retrive1(root.clone(), total); + + root + } + + /// 输入前缀和 + /// 当前节点的和 = total - left节点的和 + fn retrive1(root: Option>>, total: i32) -> i32 { + if root.is_none() { + return 0; + } + let mut prefix_sum = 0; + // 左节点 + prefix_sum += Self::retrive1(root.clone().unwrap().borrow().left.clone(), total); + + let val = root.clone().unwrap().borrow().val; + + // 当前root的和为total - 左节点的前缀和 + root.clone().unwrap().borrow_mut().val = total - prefix_sum; + prefix_sum += val; + + // 右节点 + prefix_sum += Self::retrive1( + root.clone().unwrap().borrow().right.clone(), + total - prefix_sum, + ); + + prefix_sum + } + + /// 倒叙中序遍历, 右,中,左的顺序遍历 + pub fn convert_bst(root: Option>>) -> Option>> { + let mut sum = 0; + + Self::retive(root.clone(), &mut sum); + root + } + + pub fn retive(root: Option>>, sum: &mut i32) { + if root.is_none() { + return; + } + + Self::retive(root.clone().unwrap().borrow().right.clone(), sum); + + *sum += root.clone().unwrap().borrow().val; + root.clone().unwrap().borrow_mut().val = *sum; + + Self::retive(root.clone().unwrap().borrow().left.clone(), sum); + } +} diff --git a/src/bin/convert-sorted-array-to-binary-search-tree.rs b/src/bin/convert-sorted-array-to-binary-search-tree.rs new file mode 100644 index 00000000..a6cf1bbc --- /dev/null +++ b/src/bin/convert-sorted-array-to-binary-search-tree.rs @@ -0,0 +1,46 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +// Definition for a binary tree node. +#[derive(Debug, PartialEq, Eq)] +pub struct TreeNode { + pub val: i32, + pub left: Option>>, + pub right: Option>>, +} + +impl TreeNode { + #[inline] + pub fn new(val: i32) -> Self { + TreeNode { + val, + left: None, + right: None, + } + } +} + +use std::cell::RefCell; +use std::rc::Rc; + +impl Solution { + pub fn sorted_array_to_bst(nums: Vec) -> Option>> { + Self::build(&nums) + } + + fn build(nums: &[i32]) -> Option>> { + if nums.len() == 0 { + return None; + } + + let middle = nums.len() / 2; + let mut root = TreeNode::new(nums[middle]); + root.left = Self::build(&nums[0..middle]); + root.right = Self::build(&nums[middle + 1..nums.len()]); + + Some(Rc::new(RefCell::new(root))) + } +} diff --git a/src/bin/convert-to-base-2.rs b/src/bin/convert-to-base-2.rs new file mode 100644 index 00000000..c0263c98 --- /dev/null +++ b/src/bin/convert-to-base-2.rs @@ -0,0 +1,30 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn base_neg2(n: i32) -> String { + if n == 0 { + return "0".into(); + } + let mut s = String::new(); + let mut n = n; + while n != 0 { + let mut x = n % (-2); + n /= -2; + if x == -1 { + n += 1; + x = 1; + } + + s.push_str(&x.to_string()); + } + + unsafe { + s.as_bytes_mut().reverse(); + } + s + } +} diff --git a/src/bin/count-alternating-subarrays.rs b/src/bin/count-alternating-subarrays.rs new file mode 100644 index 00000000..7d89868e --- /dev/null +++ b/src/bin/count-alternating-subarrays.rs @@ -0,0 +1,23 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn count_alternating_subarrays(nums: Vec) -> i64 { + let mut result = 0; + let mut s = 1; + + for i in 1..nums.len() { + if nums[i] == nums[i - 1] { + s = 1; + } else { + s += 1; + } + result += s; + } + + result + } +} diff --git a/src/bin/count-and-say.rs b/src/bin/count-and-say.rs new file mode 100644 index 00000000..7a3ab124 --- /dev/null +++ b/src/bin/count-and-say.rs @@ -0,0 +1,44 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + assert_eq!("1211".to_string(), Solution::count_and_say(4)); +} + +struct Solution; + +impl Solution { + pub fn count_and_say(n: i32) -> String { + if n == 1 { + return "1".to_string(); + } + let mut n = n; + let mut array = vec![1; 1]; + let mut index = 0; + + while n > 1 { + let start = array.len(); + let (mut num, mut x) = (1, array[index]); + for i in index + 1..array.len() { + if array[i] == x { + num += 1; + } else { + array.push(num); + array.push(x); + num = 1; + x = array[i]; + } + } + array.push(num); + array.push(x); + index = start; + n -= 1; + } + + let mut result = String::new(); + + for i in index..array.len() { + result.push_str(array[i].to_string().as_str()); + } + result + } +} diff --git a/src/bin/count-common-words-with-one-occurrence.rs b/src/bin/count-common-words-with-one-occurrence.rs new file mode 100644 index 00000000..1ae5a394 --- /dev/null +++ b/src/bin/count-common-words-with-one-occurrence.rs @@ -0,0 +1,35 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn count_words(words1: Vec, words2: Vec) -> i32 { + let mut hash1 = std::collections::HashMap::new(); + let mut hash2 = std::collections::HashMap::new(); + + for i in words1 { + hash1.entry(i).and_modify(|x| *x += 1).or_insert(1); + } + + for i in words2 { + hash2.entry(i).and_modify(|x| *x += 1).or_insert(1); + } + + let mut result = 0; + for (key, val) in hash1 { + if val != 1 { + continue; + } + + if let Some(x) = hash2.get(&key) { + if *x == 1 { + result += 1; + } + } + } + + result + } +} diff --git a/src/bin/count-complete-tree-nodes.rs b/src/bin/count-complete-tree-nodes.rs new file mode 100644 index 00000000..342a5739 --- /dev/null +++ b/src/bin/count-complete-tree-nodes.rs @@ -0,0 +1,90 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +// Definition for a binary tree node. +#[derive(Debug, PartialEq, Eq)] +pub struct TreeNode { + pub val: i32, + pub left: Option>>, + pub right: Option>>, +} + +impl TreeNode { + #[inline] + pub fn new(val: i32) -> Self { + TreeNode { + val, + left: None, + right: None, + } + } +} + +use std::cell::RefCell; + +use std::rc::Rc; + +impl Solution { + /// 普通遍历树,时间复杂度为O(n) + pub fn count_nodes1(root: Option>>) -> i32 { + if root.is_none() { + return 0; + } + let left = Self::count_nodes1(root.as_ref().unwrap().borrow_mut().left.take()); + let right = Self::count_nodes1(root.as_ref().unwrap().borrow_mut().right.take()); + + 1 + left + right + } + /// 二分法。 + pub fn count_nodes(root: Option>>) -> i32 { + // 获取树的高度 + fn get_level(node: Option<&Rc>>) -> i32 { + if node.is_none() { + return 0; + } + return 1 + get_level(node.unwrap().borrow().left.as_ref()); + } + + let level = get_level(root.as_ref()); + if level == 0 { + return 0; + } else if level == 1 { + return 1; + } + + let (mut min_count, mut max_count) = (2i32 << (level - 2), (2i32 << (level - 1)) - 1); + + // 查看中位的节点是否存在 + fn exists(node: Option<&Rc>>, middle: i32, level: i32) -> bool { + if level == 1 { + return node.is_some(); + } + + if ((1 << 31) | (middle << (33 - level))) == middle << (33 - level) { + exists(node.unwrap().borrow().right.as_ref(), middle, level - 1) + } else { + exists(node.unwrap().borrow().left.as_ref(), middle, level - 1) + } + } + + while max_count - min_count > 1 { + let middle = (min_count + max_count) / 2; + + let e = exists(root.as_ref(), middle, level); + if e { + min_count = middle; + } else { + max_count = middle - 1; + } + } + + if max_count - min_count == 1 && exists(root.as_ref(), max_count, level) { + max_count + } else { + min_count + } + } +} diff --git a/src/bin/count-distinct-numbers-on-board.rs b/src/bin/count-distinct-numbers-on-board.rs new file mode 100644 index 00000000..708a43ac --- /dev/null +++ b/src/bin/count-distinct-numbers-on-board.rs @@ -0,0 +1,15 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn distinct_integers(n: i32) -> i32 { + if n > 1 { + n - 1 + } else { + 1 + } + } +} diff --git a/src/bin/count-elements-with-strictly-smaller-and-greater-elements.rs b/src/bin/count-elements-with-strictly-smaller-and-greater-elements.rs new file mode 100644 index 00000000..2f691176 --- /dev/null +++ b/src/bin/count-elements-with-strictly-smaller-and-greater-elements.rs @@ -0,0 +1,54 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn count_elements1(nums: Vec) -> i32 { + let (mut min, mut max) = (i32::MAX, i32::MIN); + + for &i in nums.iter() { + min = min.min(i); + max = max.max(i); + } + + let mut result = 0; + + for i in nums { + if i > min && i < max { + result += 1; + } + } + + result + } + + /// 统计最大值和最小值的个数,然后总数-最大值和最小值的个数即为结果 + pub fn count_elements(nums: Vec) -> i32 { + let (mut min, mut max) = (nums[0], nums[0]); + let (mut min_count, mut max_count) = (1, 1); + + for &i in nums[1..].iter() { + if i < min { + min = i; + min_count = 1; + } else if i == min { + min_count += 1; + } + + if i > max { + max = i; + max_count = 1; + } else if i == max { + max_count += 1; + } + } + + if min == max { + 0 + } else { + nums.len() as i32 - max_count - min_count + } + } +} diff --git a/src/bin/count-good-nodes-in-binary-tree.rs b/src/bin/count-good-nodes-in-binary-tree.rs new file mode 100644 index 00000000..c8c599f2 --- /dev/null +++ b/src/bin/count-good-nodes-in-binary-tree.rs @@ -0,0 +1,55 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +// Definition for a binary tree node. +#[derive(Debug, PartialEq, Eq)] +pub struct TreeNode { + pub val: i32, + pub left: Option>>, + pub right: Option>>, +} + +impl TreeNode { + #[inline] + pub fn new(val: i32) -> Self { + TreeNode { + val, + left: None, + right: None, + } + } +} +use std::cell::RefCell; +use std::rc::Rc; +impl Solution { + pub fn good_nodes(root: Option>>) -> i32 { + if root.is_none() { + return 0; + } + + let left = root.as_ref().unwrap().borrow_mut().left.take(); + let right = root.as_ref().unwrap().borrow_mut().right.take(); + let value = root.as_ref().unwrap().borrow().val; + + 1 + Self::f(value, left) + Self::f(value, right) + } + + fn f(max: i32, root: Option>>) -> i32 { + if root.is_none() { + return 0; + } + + let left = root.as_ref().unwrap().borrow_mut().left.take(); + let right = root.as_ref().unwrap().borrow_mut().right.take(); + let value = root.as_ref().unwrap().borrow().val; + + if value >= max { + 1 + Self::f(value, left) + Self::f(value, right) + } else { + Self::f(max, left) + Self::f(max, right) + } + } +} diff --git a/src/bin/count-good-triplets.rs b/src/bin/count-good-triplets.rs new file mode 100644 index 00000000..3b0120d3 --- /dev/null +++ b/src/bin/count-good-triplets.rs @@ -0,0 +1,28 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + println!("{}", !10); +} + +struct Solution; + +impl Solution { + /// 穷举,暴力破解 + pub fn count_good_triplets(arr: Vec, a: i32, b: i32, c: i32) -> i32 { + let mut count = 0; + for i in 0..arr.len() { + for j in i + 1..arr.len() { + if !((arr[i] - arr[j]).abs() <= a) { + continue; + } + + for k in j + 1..arr.len() { + if (arr[j] - arr[k]).abs() <= b && (arr[i] - arr[k]).abs() <= c { + count += 1; + } + } + } + } + count + } +} diff --git a/src/bin/count-items-matching-a-rule.rs b/src/bin/count-items-matching-a-rule.rs new file mode 100644 index 00000000..bb5a818f --- /dev/null +++ b/src/bin/count-items-matching-a-rule.rs @@ -0,0 +1,19 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn count_matches(items: Vec>, rule_key: String, rule_value: String) -> i32 { + items + .into_iter() + .filter(|x| match rule_key.as_str() { + "type" => x[0] == rule_value, + "color" => x[1] == rule_value, + "name" => x[2] == rule_value, + _ => unreachable!(), + }) + .count() as i32 + } +} diff --git a/src/bin/count-lattice-points-inside-a-circle.rs b/src/bin/count-lattice-points-inside-a-circle.rs new file mode 100644 index 00000000..3172a42c --- /dev/null +++ b/src/bin/count-lattice-points-inside-a-circle.rs @@ -0,0 +1,34 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn count_lattice_points(circles: Vec>) -> i32 { + let mut max_x = -1; + let mut max_y = -1; + let mut min_x = i32::MAX; + let mut min_y = i32::MAX; + let mut result = 0; + for i in circles.iter() { + max_x = max_x.max(i[0] + i[2]); + max_y = max_y.max(i[1] + i[2]); + min_x = min_x.min(i[0] - i[2]); + min_y = min_y.min(i[1] - i[2]); + } + + for i in min_x..=max_x { + for j in min_y..=max_y { + for c in circles.iter() { + if (i - c[0]).pow(2) + (j - c[1]).pow(2) <= c[2].pow(2) { + result += 1; + break; + } + } + } + } + + result + } +} diff --git a/src/bin/count-number-of-nice-subarrays.rs b/src/bin/count-number-of-nice-subarrays.rs new file mode 100644 index 00000000..0759e1a4 --- /dev/null +++ b/src/bin/count-number-of-nice-subarrays.rs @@ -0,0 +1,51 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + println!( + "{}", + Solution::number_of_subarrays(vec![2, 2, 2, 1, 2, 2, 1, 2, 2, 2], 2) + ); + println!( + "{}", + Solution::number_of_subarrays(vec![2, 2, 2, 1, 2, 2, 1, 2, 2, 2, 1], 2) + ); +} + +struct Solution; + +impl Solution { + pub fn number_of_subarrays(nums: Vec, k: i32) -> i32 { + let mut count = 0usize; + let mut index_list: Vec = vec![]; // 用于存放奇数元素索引的数组 + let k = k as usize; + + for (index, &value) in nums.iter().enumerate() { + if value % 2 == 1 { + index_list.push(index); + } + } + + if index_list.len() < k { + return count as i32; + } + + for (index, &value) in index_list.iter().skip(k - 1).enumerate() { + let mut s = 0; + let mut t = 0; + if index == 0 { + s = index_list[0] + 1; + } else { + s = index_list[index] - index_list[index - 1]; + } + + if index + k == index_list.len() { + t = nums.len() - value; + } else { + t = index_list[index + k] - index_list[index + k - 1]; + } + count += s * t; + } + + count as i32 + } +} diff --git a/src/bin/count-numbers-with-unique-digits.rs b/src/bin/count-numbers-with-unique-digits.rs new file mode 100644 index 00000000..8ec37450 --- /dev/null +++ b/src/bin/count-numbers-with-unique-digits.rs @@ -0,0 +1,29 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + println!("{}", Solution::count_numbers_with_unique_digits(2)); + println!("{}", Solution::count_numbers_with_unique_digits(8)); + println!("{}", Solution::count_numbers_with_unique_digits(7)); +} + +struct Solution; + +impl Solution { + pub fn count_numbers_with_unique_digits(n: i32) -> i32 { + if n == 0 { + return 1; + } + + if n == 1 { + return 10; + } + + let mut sum = 9; + + for i in 0..n - 1 { + sum *= 9 - i; + } + + sum + Self::count_numbers_with_unique_digits(n - 1) + } +} diff --git a/src/bin/count-odd-numbers-in-an-interval-range.rs b/src/bin/count-odd-numbers-in-an-interval-range.rs new file mode 100644 index 00000000..31e40c5c --- /dev/null +++ b/src/bin/count-odd-numbers-in-an-interval-range.rs @@ -0,0 +1,21 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn count_odds(low: i32, high: i32) -> i32 { + let mut low = low; + let mut high = high; + if low % 2 == 0 { + low += 1; + } + + if high % 2 == 0 { + high -= 1; + } + + (high - low) / 2 + 1 + } +} diff --git a/src/bin/count-of-matches-in-tournament.rs b/src/bin/count-of-matches-in-tournament.rs new file mode 100644 index 00000000..184744ac --- /dev/null +++ b/src/bin/count-of-matches-in-tournament.rs @@ -0,0 +1,35 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + assert_eq!(6, Solution::number_of_matches(7)); +} + +struct Solution; + +impl Solution { + pub fn number_of_matches(mut n: i32) -> i32 { + let mut count = 0; + + while n > 0 { + if n % 2 == 0 { + count += n / 2; + n = n / 2; + } else { + if n == 1 { + n = 0; + } else { + count += n / 2; + n = n / 2 + 1; + } + } + } + + count + } + /// 找规律,就n-1 + /// n个选手,决定一个冠军,则需要淘汰n-1个选手 + /// 每场淘汰1个选手,因此需要n-1场比赛,所以需要配对n-1次 + pub fn number_of_matches1(n: i32) -> i32 { + n - 1 + } +} diff --git a/src/bin/count-pairs-whose-sum-is-less-than-target.rs b/src/bin/count-pairs-whose-sum-is-less-than-target.rs new file mode 100644 index 00000000..f94d47b1 --- /dev/null +++ b/src/bin/count-pairs-whose-sum-is-less-than-target.rs @@ -0,0 +1,40 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn count_pairs(nums: Vec, target: i32) -> i32 { + if nums.len() < 2 { + return 0; + } + + let mut nums = nums; + nums.sort(); + + let (mut s1, mut s2) = (0, 1); // 双指针 + let mut result = 0; + + for i in 1..nums.len() { + result += Self::search(target - nums[i], &nums[..i]); + } + + result + } + + fn search(target: i32, nums: &[i32]) -> i32 { + let (mut start, mut end) = (0, nums.len()); + + while start < end { + let middle = start + (end - start) / 2; + if nums[middle] < target { + start = middle + 1; + } else { + end = middle; + } + } + + end as i32 + } +} diff --git a/src/bin/count-primes.rs b/src/bin/count-primes.rs new file mode 100644 index 00000000..20b2a22e --- /dev/null +++ b/src/bin/count-primes.rs @@ -0,0 +1,79 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + assert_eq!(4, Solution::count_primes(10)); +} + +struct Solution; + +impl Solution { + pub fn count_primes1(n: i32) -> i32 { + if n == 0 || n == 1 { + return 0; + } + + // 0代表是质数,1代表非质数 + let mut v = vec![0; (n - 2) as usize]; + + for i in 2..n { + if v[i as usize - 2] == 1 { + continue; + } + + if Self::is_prim(i) { + v[i as usize - 2] = 0; + let mut m = i * 2; + while m < n { + v[m as usize - 2] = 1; + m *= 2; + } + } else { + v[i as usize - 2] = 1; + } + } + println!("{:?}", v); + v.into_iter().filter(|x| *x == 0).count() as i32 + } + + fn is_prim(n: i32) -> bool { + if n == 2 || n == 3 { + return true; + } + + let mut i = 3; + + while i * i <= n { + if n % i == 0 { + return false; + } + i += 2; + } + + true + } + + pub fn count_primes(n: i32) -> i32 { + if n == 0 || n == 1 { + return 0; + } + + // 0代表是质数,1代表非质数 + let mut v = vec![true; n as usize]; + let mut start = 2usize; + let mut count = 0; + while start < n as usize { + if v[start] { + count += 1; + + let mut start1 = start * 2; + while start1 < n as usize { + v[start1] = false; + start1 += start; + } + } + start += 1; + } + + count + } +} diff --git a/src/bin/count-servers-that-communicate.rs b/src/bin/count-servers-that-communicate.rs new file mode 100644 index 00000000..5ea29be7 --- /dev/null +++ b/src/bin/count-servers-that-communicate.rs @@ -0,0 +1,38 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn count_servers(grid: Vec>) -> i32 { + let (mut row, mut col) = ( + std::collections::HashMap::new(), + std::collections::HashMap::new(), + ); + + let mut result = 0; + + for i in 0..grid.len() { + for j in 0..grid[0].len() { + if grid[i][j] == 1 { + row.entry(i).and_modify(|x| *x += 1).or_insert(1); + col.entry(j).and_modify(|x| *x += 1).or_insert(1); + } + } + } + + for i in 0..grid.len() { + for j in 0..grid[0].len() { + if grid[i][j] == 1 { + match (row.get(&i), col.get(&j)) { + (Some(&x), Some(&y)) if x > 1 || y > 1 => result += 1, + _ => {} + } + } + } + } + + result + } +} diff --git a/src/bin/count-tested-devices-after-test-operations.rs b/src/bin/count-tested-devices-after-test-operations.rs new file mode 100644 index 00000000..d4408e08 --- /dev/null +++ b/src/bin/count-tested-devices-after-test-operations.rs @@ -0,0 +1,19 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn count_tested_devices(battery_percentages: Vec) -> i32 { + let mut result = 0; + + for i in battery_percentages { + if i > result { + result += 1; + } + } + + result + } +} diff --git a/src/bin/count-the-digits-that-divide-a-number.rs b/src/bin/count-the-digits-that-divide-a-number.rs new file mode 100644 index 00000000..f0fa0ebd --- /dev/null +++ b/src/bin/count-the-digits-that-divide-a-number.rs @@ -0,0 +1,21 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn count_digits(num: i32) -> i32 { + let mut n = num; + let mut r = 0; + while n > 0 { + if num % (n % 10) == 0 { + r += 1; + } + + n /= 10; + } + + r + } +} diff --git a/src/bin/count-the-number-of-vowel-strings-in-range.rs b/src/bin/count-the-number-of-vowel-strings-in-range.rs new file mode 100644 index 00000000..0b74a1a3 --- /dev/null +++ b/src/bin/count-the-number-of-vowel-strings-in-range.rs @@ -0,0 +1,15 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn vowel_strings(words: Vec, left: i32, right: i32) -> i32 { + words[left as usize..=right as usize] + .into_iter() + .filter(|x| x.starts_with(|x| matches!(x, 'a' | 'e' | 'i' | 'o' | 'u'))) + .filter(|x| x.ends_with(|x| matches!(x, 'a' | 'e' | 'i' | 'o' | 'u'))) + .count() as i32 + } +} diff --git a/src/bin/count-vowel-strings-in-ranges.rs b/src/bin/count-vowel-strings-in-ranges.rs new file mode 100644 index 00000000..882ae79f --- /dev/null +++ b/src/bin/count-vowel-strings-in-ranges.rs @@ -0,0 +1,28 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn vowel_strings(words: Vec, queries: Vec>) -> Vec { + let mut s = vec![0; words.len() + 1]; + + for (i, v) in words.iter().enumerate() { + if matches!(v.as_bytes()[0], b'a' | b'e' | b'i' | b'o' | b'u') + && matches!(v.as_bytes()[v.len() - 1], b'a' | b'e' | b'i' | b'o' | b'u') + { + s[i + 1] = s[i] + 1; + } else { + s[i + 1] = s[i]; + } + } + + let mut result = Vec::with_capacity(queries.len()); + for i in queries.into_iter() { + result.push(s[i[1] as usize + 1] - s[i[0] as usize]); + } + + result + } +} diff --git a/src/bin/count-ways-to-group-overlapping-ranges.rs b/src/bin/count-ways-to-group-overlapping-ranges.rs new file mode 100644 index 00000000..ec891a3e --- /dev/null +++ b/src/bin/count-ways-to-group-overlapping-ranges.rs @@ -0,0 +1,24 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn count_ways(ranges: Vec>) -> i32 { + let mut ranges = ranges; + ranges.sort(); + let mut max = -1; + let mut m = 1; + + for range in ranges { + if range[0] > max { + m = m * 2 % 1000000007; + } + + max = max.max(range[1]); + } + + m + } +} diff --git a/src/bin/counting-bits.rs b/src/bin/counting-bits.rs new file mode 100644 index 00000000..2e288c69 --- /dev/null +++ b/src/bin/counting-bits.rs @@ -0,0 +1,36 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +use std::vec; + +fn main() { + assert_eq!(Solution::count_bits(5), vec![0, 1, 1, 2, 1, 2]); + assert_eq!( + Solution::count_bits(10), + vec![0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2] + ); +} + +struct Solution; + +impl Solution { + pub fn count_bits(n: i32) -> Vec { + if n == 0 { + return vec![0]; + } + + let mut r = vec![0; n as usize + 1]; + let mut start = 0; + let mut mask = 1; + for i in 1..=n as usize { + if i == mask { + start = 0; + mask *= 2; + } + + r[i] = r[start] + 1; + start += 1; + } + + r + } +} diff --git a/src/bin/counting-words-with-a-given-prefix.rs b/src/bin/counting-words-with-a-given-prefix.rs new file mode 100644 index 00000000..92ee365d --- /dev/null +++ b/src/bin/counting-words-with-a-given-prefix.rs @@ -0,0 +1,11 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn prefix_count(words: Vec, pref: String) -> i32 { + words.into_iter().filter(|x| x.starts_with(&pref)).count() as i32 + } +} diff --git a/src/bin/course-schedule.rs b/src/bin/course-schedule.rs new file mode 100644 index 00000000..0f01930d --- /dev/null +++ b/src/bin/course-schedule.rs @@ -0,0 +1,66 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +struct Node { + /// 入度个数 + indegrees: i32, + /// 出度列表 + adjacency: Vec, +} + +impl Solution { + /// 有向图 + /// 看是否有环 + /// m[a] = b, a为课程编号,b为依赖a的课程 + pub fn can_finish(num_courses: i32, prerequisites: Vec>) -> bool { + if prerequisites.is_empty() { + return true; + } + + let mut h = std::collections::HashMap::new(); + + for i in prerequisites.iter() { + h.entry(i[1]) + .or_insert(Node { + indegrees: 0, + adjacency: vec![], + }) + .adjacency + .push(i[0]); + + h.entry(i[0]) + .or_insert(Node { + indegrees: 0, + adjacency: vec![], + }) + .indegrees += 1; + } + + let mut stack = vec![]; + for (&i, node) in h.iter() { + if node.indegrees == 0 { + stack.push(i); + } + } + + let mut count = 0; + + while let Some(x) = stack.pop() { + count += 1; + + let node = h.remove(&x).unwrap(); + + for i in node.adjacency { + h.entry(i).and_modify(|x| x.indegrees -= 1); + if h.get(&i).unwrap().indegrees == 0 { + stack.push(i); + } + } + } + + h.is_empty() || count >= num_courses + } +} diff --git a/src/bin/cousins-in-binary-tree.rs b/src/bin/cousins-in-binary-tree.rs new file mode 100644 index 00000000..e6b9c189 --- /dev/null +++ b/src/bin/cousins-in-binary-tree.rs @@ -0,0 +1,75 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +use std::cell::RefCell; +use std::rc::Rc; + +fn main() {} + +struct Solution; + +// Definition for a binary tree node. +#[derive(Debug, PartialEq, Eq)] +pub struct TreeNode { + pub val: i32, + pub left: Option>>, + pub right: Option>>, +} + +impl TreeNode { + #[inline] + pub fn new(val: i32) -> Self { + TreeNode { + val, + left: None, + right: None, + } + } +} + +impl Solution { + pub fn is_cousins(root: Option>>, x: i32, y: i32) -> bool { + let mut stack = vec![root]; + while !stack.is_empty() { + let mut new_stack = vec![]; + let mut exists = false; + while let Some(Some(p)) = stack.pop() { + let left = p.borrow_mut().left.take(); + let right = p.borrow_mut().right.take(); + let mut e = false; + if left.is_some() { + let v = left.as_ref().unwrap().borrow().val; + if v == x || v == y { + if exists { + return true; + } + exists = true; + e = true; + } + + new_stack.push(left); + } + + if right.is_some() { + let v = right.as_ref().unwrap().borrow().val; + if v == x || v == y { + if e { + return false; + } + + if exists { + return true; + } + + exists = true; + } + + new_stack.push(right); + } + } + + stack = new_stack; + } + + false + } +} diff --git a/src/bin/create-target-array-in-the-given-order.rs b/src/bin/create-target-array-in-the-given-order.rs new file mode 100644 index 00000000..60b76ed7 --- /dev/null +++ b/src/bin/create-target-array-in-the-given-order.rs @@ -0,0 +1,17 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn create_target_array(nums: Vec, index: Vec) -> Vec { + let mut s = Vec::new(); + + for i in 0..nums.len() { + s.insert(index[i] as usize, nums[i]); + } + + s + } +} diff --git a/src/bin/dKk3P7.rs b/src/bin/dKk3P7.rs new file mode 100644 index 00000000..2cb89c14 --- /dev/null +++ b/src/bin/dKk3P7.rs @@ -0,0 +1,36 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn is_anagram(s: String, t: String) -> bool { + if s.len() != t.len() { + return false; + } + + let mut v = [0; 26]; + let mut f = false; + for i in 0..s.len() { + if !f && s.as_bytes()[i] != t.as_bytes()[i] { + f = true; + } + + v[(s.as_bytes()[i] - b'a') as usize] += 1; + v[(t.as_bytes()[i] - b'a') as usize] -= 1; + } + + if !f { + return false; + } + + for i in v { + if i != 0 { + return false; + } + } + + true + } +} diff --git a/src/bin/da-yin-cong-1dao-zui-da-de-nwei-shu-lcof.rs b/src/bin/da-yin-cong-1dao-zui-da-de-nwei-shu-lcof.rs new file mode 100644 index 00000000..86715bf8 --- /dev/null +++ b/src/bin/da-yin-cong-1dao-zui-da-de-nwei-shu-lcof.rs @@ -0,0 +1,13 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() { + println!("{:?}", Solution::print_numbers(3)); +} + +struct Solution; + +impl Solution { + pub fn print_numbers(n: i32) -> Vec { + (1..10i32.pow(n as u32)).collect() + } +} diff --git a/src/bin/daily-temperatures.rs b/src/bin/daily-temperatures.rs new file mode 100644 index 00000000..2a7f8eb0 --- /dev/null +++ b/src/bin/daily-temperatures.rs @@ -0,0 +1,31 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +use std::vec; + +fn main() {} + +struct Solution; + +impl Solution { + /// 单调栈保存单调递减的温度, + /// 遍历到一个温度时,弹出单调栈顶的元素,如果当前温度比栈顶的温度高,则就是第一次出现大于栈顶的温度,直接下标求差即为相差的天数。 + /// 然后把当前温度入栈。 + pub fn daily_temperatures(temperatures: Vec) -> Vec { + let mut stack = vec![]; + let mut ans = vec![0; temperatures.len()]; + for i in 0..temperatures.len() { + while !stack.is_empty() { + if temperatures[stack[stack.len() - 1]] < temperatures[i] { + ans[stack[stack.len() - 1]] = (i - (stack[stack.len() - 1])) as i32; + stack.pop(); + } else { + break; + } + } + + stack.push(i); + } + + ans + } +} diff --git a/src/bin/day-of-the-week.rs b/src/bin/day-of-the-week.rs new file mode 100644 index 00000000..88daf489 --- /dev/null +++ b/src/bin/day-of-the-week.rs @@ -0,0 +1,46 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn day_of_the_week(day: i32, month: i32, year: i32) -> String { + let mut start = 3i32; + + for i in 1970..year { + start += 365; + if i % 4 == 0 { + if i % 100 == 0 && i % 400 != 0 { + continue; + } + + start += 1; + } + } + + const MONTH: [i32; 12] = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; + for i in 1..month { + start += MONTH[i as usize - 1]; + if i == 2 && year % 4 == 0 { + if year % 100 == 0 && year % 400 != 0 { + continue; + } + start += 1; + } + } + + start += day; + + match start % 7 { + 0 => "Sunday".into(), + 1 => "Monday".into(), + 2 => "Tuesday".into(), + 3 => "Wednesday".into(), + 4 => "Thursday".into(), + 5 => "Friday".into(), + 6 => "Saturday".into(), + _ => unreachable!(), + } + } +} diff --git a/src/bin/day-of-the-year.rs b/src/bin/day-of-the-year.rs new file mode 100644 index 00000000..e8080bfc --- /dev/null +++ b/src/bin/day-of-the-year.rs @@ -0,0 +1,29 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn day_of_year(date: String) -> i32 { + let mut d = date.split('-'); + let year = d.next().unwrap().parse::().unwrap(); + let month = d.next().unwrap().parse::().unwrap(); + let day = d.next().unwrap().parse::().unwrap(); + + let mut result = 0; + const MONTH: [i32; 12] = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; + + for i in 1..month { + result += MONTH[i as usize - 1]; + if i == 2 && year % 4 == 0 { + if year % 100 == 0 && year % 400 != 0 { + continue; + } + result += 1; + } + } + + result + day + } +} diff --git a/src/bin/decode-ways.rs b/src/bin/decode-ways.rs new file mode 100644 index 00000000..f7ded205 --- /dev/null +++ b/src/bin/decode-ways.rs @@ -0,0 +1,57 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + println!("{}", Solution::num_decodings("12".to_string())); + println!("{}", Solution::num_decodings("06".to_string())); + println!( + "{}", + Solution::num_decodings("2611055971756562".to_string()) + ); + println!( + "{}", + Solution::num_decodings("111111111111111111111111111111111111111111111".to_string()) + ); +} + +struct Solution; + +impl Solution { + pub fn num_decodings(s: String) -> i32 { + if s.starts_with('0') { + return 0; + } + + let mut v = vec![-1; s.len()]; + + Self::f(s.as_bytes(), &mut v) + } + + fn f(s: &[u8], v: &mut Vec) -> i32 { + let mut r = 0; + let l = s.len(); + + if l > 0 { + if v[l - 1] != -1 { + r = v[l - 1]; + } else { + if s[0] != b'0' { + if l > 1 { + if (s[0] == b'2' && s[1] <= b'6') || s[0] < b'2' { + r += Self::f(&s[2..], v); + } + + if s[1] != b'0' { + r += Self::f(&s[1..], v); + } + } else { + r += Self::f(&s[1..], v); + } + } + } + v[l - 1] = r; + } else { + r = 1; + } + r + } +} diff --git a/src/bin/decrypt-string-from-alphabet-to-integer-mapping.rs b/src/bin/decrypt-string-from-alphabet-to-integer-mapping.rs index 742e1625..a427e181 100644 --- a/src/bin/decrypt-string-from-alphabet-to-integer-mapping.rs +++ b/src/bin/decrypt-string-from-alphabet-to-integer-mapping.rs @@ -1,3 +1,5 @@ +#![allow(dead_code, unused, unused_variables)] + fn main() { println!("{}", Solution::freq_alphabets("10#11#12".to_string())); println!("{}", Solution::freq_alphabets("1326#".to_string())); @@ -14,13 +16,13 @@ impl Solution { while index < bytes.len() { if index + 2 < bytes.len() && bytes[index + 2] == '#' as u8 { - result.push((96 + (bytes[index]-48)* 10 + (bytes[index + 1]-48)) as char); + result.push((96 + (bytes[index] - 48) * 10 + (bytes[index + 1] - 48)) as char); index += 3; } else { - result.push((96 + bytes[index]-48) as char); + result.push((96 + bytes[index] - 48) as char); index += 1; } } result } -} \ No newline at end of file +} diff --git a/src/bin/defuse-the-bomb.rs b/src/bin/defuse-the-bomb.rs new file mode 100644 index 00000000..91d84071 --- /dev/null +++ b/src/bin/defuse-the-bomb.rs @@ -0,0 +1,47 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() { + assert_eq!(Solution::decrypt(vec![5, 7, 1, 4], 3), vec![12, 10, 16, 13]); + assert_eq!(Solution::decrypt(vec![1, 2, 3, 4], 0), vec![0, 0, 0, 0]); + assert_eq!(Solution::decrypt(vec![2, 4, 9, 3], -2), vec![12, 5, 6, 13]); +} + +struct Solution; + +impl Solution { + pub fn decrypt(code: Vec, k: i32) -> Vec { + let mut result = vec![0; code.len()]; + let mut code = code; + + for i in 1..code.len() { + code[i] += code[i - 1]; + } + + for i in 0..code.len() { + match k { + 0 => result[i] = 0, + _x if _x > 0 => { + if (i + k as usize) < code.len() { + result[i] = code[i + k as usize] - code[i]; + } else { + result[i] += code[code.len() - 1] - code[i]; + result[i] += code[k as usize - (code.len() - 1 - i) - 1]; + } + } + _ => { + let k = -k; + if i >= k as usize + 1 { + result[i] = code[i - 1] - code[i - k as usize - 1]; + } else { + result[i] += code[code.len() - 1] - code[code.len() - 1 - (k as usize - i)]; + if i != 0 { + result[i] += code[i - 1]; + } + } + } + } + } + + result + } +} diff --git a/src/bin/delete-columns-to-make-sorted.rs b/src/bin/delete-columns-to-make-sorted.rs new file mode 100644 index 00000000..cca62e95 --- /dev/null +++ b/src/bin/delete-columns-to-make-sorted.rs @@ -0,0 +1,23 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn min_deletion_size(strs: Vec) -> i32 { + let mut count = 0; + + for i in 0..strs[0].len() { + for j in 1..strs.len() { + let s = strs[j - 1].as_bytes(); + let s1 = strs[j].as_bytes(); + if s[i] > s1[i] { + count += 1; + break; + } + } + } + count + } +} diff --git a/src/bin/delete-greatest-value-in-each-row.rs b/src/bin/delete-greatest-value-in-each-row.rs new file mode 100644 index 00000000..41665fa9 --- /dev/null +++ b/src/bin/delete-greatest-value-in-each-row.rs @@ -0,0 +1,24 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn delete_greatest_value(mut grid: Vec>) -> i32 { + grid.iter_mut().for_each(|x| x.sort_by_key(|k| -k)); + + let mut r = 0; + + for i in 0..grid[0].len() { + let mut max = 0; + for j in 0..grid.len() { + max = max.max(grid[j][i]); + } + + r += max; + } + + r + } +} diff --git a/src/bin/delete-leaves-with-a-given-value.rs b/src/bin/delete-leaves-with-a-given-value.rs new file mode 100644 index 00000000..92ed445b --- /dev/null +++ b/src/bin/delete-leaves-with-a-given-value.rs @@ -0,0 +1,58 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +use std::cell::RefCell; +use std::rc::Rc; + +fn main() {} + +struct Solution; + +// Definition for a binary tree node. +#[derive(Debug, PartialEq, Eq)] +pub struct TreeNode { + pub val: i32, + pub left: Option>>, + pub right: Option>>, +} + +impl TreeNode { + #[inline] + pub fn new(val: i32) -> Self { + TreeNode { + val, + left: None, + right: None, + } + } +} + +impl Solution { + pub fn remove_leaf_nodes( + root: Option>>, + target: i32, + ) -> Option>> { + if root.is_none() { + return None; + } + + let left = Self::remove_leaf_nodes( + root.as_ref() + .map_or_else(|| None, |x| x.borrow_mut().left.take()), + target, + ); + let right = Self::remove_leaf_nodes( + root.as_ref() + .map_or_else(|| None, |x| x.borrow_mut().right.take()), + target, + ); + + if left.is_none() && right.is_none() && root.as_ref().unwrap().borrow().val == target { + return None; + } + + root.as_ref().unwrap().borrow_mut().left = left; + root.as_ref().unwrap().borrow_mut().right = right; + + root + } +} diff --git a/src/bin/design-add-and-search-words-data-structure.rs b/src/bin/design-add-and-search-words-data-structure.rs new file mode 100644 index 00000000..0c19bae7 --- /dev/null +++ b/src/bin/design-add-and-search-words-data-structure.rs @@ -0,0 +1,116 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +/** + * Your WordDictionary object will be instantiated and called as such: + * let obj = WordDictionary::new(); + * obj.add_word(word); + * let ret_2: bool = obj.search(word); + */ +struct WordDictionary { + root: Vec>>, +} + +struct Node { + table: Vec>>, + // 到此节点是否为一个单词 + is_word: bool, +} + +impl Node { + fn new(is_word: bool) -> Self { + let mut table = Vec::with_capacity(26); + for _i in 0..26 { + table.push(None); + } + + Self { table, is_word } + } +} + +/** + * `&self` means the method takes an immutable reference. + * If you need a mutable reference, change it to `&mut self` instead. + */ +impl WordDictionary { + /** Initialize your data structure here. */ + fn new() -> Self { + let mut root = Vec::with_capacity(26); + for _i in 0..26 { + root.push(None); + } + + Self { root } + } + + fn add_word(&mut self, word: String) { + Self::add(&mut self.root[..], word.as_bytes()); + } + + fn add(table: &mut [Option>], letter: &[u8]) { + if letter.len() == 0 { + return; + } + + let is_word = letter.len() == 1; + + let s = if letter[0] == b'.' { + b'a'..=b'z' + } else { + letter[0]..=letter[0] + }; + + for i in s { + let mut node = table[(i - b'a') as usize].as_mut(); + if node.is_none() { + table[(i - b'a') as usize] = Some(Box::new(Node::new(is_word))); + } else { + if is_word { + node.as_mut().unwrap().is_word = is_word; + } + } + + Self::add( + table[(i - b'a') as usize].as_mut().unwrap().table.as_mut(), + &letter[1..], + ); + } + } + + fn search(&self, word: String) -> bool { + Self::search_by_slice(&self.root[..], word.as_bytes()) + } + + fn search_by_slice(table: &[Option>], letter: &[u8]) -> bool { + if letter.len() == 0 { + return false; + } + + let s = if letter[0] == b'.' { + b'a'..=b'z' + } else { + letter[0]..=letter[0] + }; + for i in s { + let node = table[(i - b'a') as usize].as_ref(); + if node.is_none() { + continue; + } + + if letter.len() == 1 { + if node.as_ref().unwrap().is_word { + return true; + } + } + + if Self::search_by_slice(node.as_ref().unwrap().table.as_ref(), &letter[1..]) { + return true; + } + } + + false + } +} diff --git a/src/bin/design-authentication-manager.rs b/src/bin/design-authentication-manager.rs new file mode 100644 index 00000000..68968b35 --- /dev/null +++ b/src/bin/design-authentication-manager.rs @@ -0,0 +1,50 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +struct AuthenticationManager { + storage: std::collections::HashMap, + ttl: i32, +} + +/** + * `&self` means the method takes an immutable reference. + * If you need a mutable reference, change it to `&mut self` instead. + */ +/** + * Your AuthenticationManager object will be instantiated and called as such: + * let obj = AuthenticationManager::new(timeToLive); + * obj.generate(tokenId, currentTime); + * obj.renew(tokenId, currentTime); + * let ret_3: i32 = obj.count_unexpired_tokens(currentTime); + */ +impl AuthenticationManager { + fn new(timeToLive: i32) -> Self { + Self { + ttl: timeToLive, + storage: std::collections::HashMap::new(), + } + } + + fn generate(&mut self, token_id: String, current_time: i32) { + self.storage.insert(token_id, current_time); + } + + fn renew(&mut self, token_id: String, current_time: i32) { + match self.storage.remove(&token_id) { + Some(x) if x + self.ttl > current_time => { + self.storage.insert(token_id, current_time); + } + _ => {} + } + } + + fn count_unexpired_tokens(&self, current_time: i32) -> i32 { + self.storage + .values() + .filter(|x| *x + self.ttl > current_time) + .count() as i32 + } +} diff --git a/src/bin/design-bitset.rs b/src/bin/design-bitset.rs new file mode 100644 index 00000000..7a257c08 --- /dev/null +++ b/src/bin/design-bitset.rs @@ -0,0 +1,102 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +/** + * `&self` means the method takes an immutable reference. + * If you need a mutable reference, change it to `&mut self` instead. + */ + +/** + * Your Bitset object will be instantiated and called as such: + * let obj = Bitset::new(size); + * obj.fix(idx); + * obj.unfix(idx); + * obj.flip(); + * let ret_4: bool = obj.all(); + * let ret_5: bool = obj.one(); + * let ret_6: i32 = obj.count(); + * let ret_7: String = obj.to_string(); + */ + +struct Bitset { + data: Vec, + size: i32, + count: i32, +} + +impl Bitset { + fn new(size: i32) -> Self { + Self { + data: vec![0; size as usize / 8 + 1], + size, + count: 0, + } + } + + fn set(&mut self, idx: usize, val: u8) { + let index = idx / 8; + let n = idx % 8; + if val == 1 { + let d = 0b1 << (7 - n); + if self.data[index] != self.data[index] | d { + self.count += 1; + self.data[index] = self.data[index] | d; + } + } else { + let d = 0b11111111 ^ (0b1 << (7 - n)); + if self.data[index] != self.data[index] & d { + self.count -= 1; + self.data[index] = self.data[index] & d; + } + } + } + + fn fix(&mut self, idx: i32) { + self.set(idx as usize, 1); + } + + fn unfix(&mut self, idx: i32) { + self.set(idx as usize, 0) + } + + fn flip(&mut self) { + self.count = self.size - self.count; + + for i in 0..self.data.len() { + self.data[i] = !self.data[i]; + } + } + + fn all(&self) -> bool { + self.count == self.size + } + + fn one(&self) -> bool { + self.count > 0 + } + + fn count(&self) -> i32 { + self.count + } + + fn to_string(&self) -> String { + let mut s = String::with_capacity(self.size as usize); + + 'b: for i in 0..self.data.len() { + for index in 0..8 { + if i * 8 + index >= self.size as usize { + break 'b; + } + if self.data[i] >> (7 - index) & 0b1 == 0b1 { + s.push('1'); + } else { + s.push('0'); + } + } + } + s + } +} diff --git a/src/bin/design-circular-queue.rs b/src/bin/design-circular-queue.rs new file mode 100644 index 00000000..d1d3c0e2 --- /dev/null +++ b/src/bin/design-circular-queue.rs @@ -0,0 +1,99 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +/** + * Your MyCircularQueue object will be instantiated and called as such: + * let obj = MyCircularQueue::new(k); + * let ret_1: bool = obj.en_queue(value); + * let ret_2: bool = obj.de_queue(); + * let ret_3: i32 = obj.front(); + * let ret_4: i32 = obj.rear(); + * let ret_5: bool = obj.is_empty(); + * let ret_6: bool = obj.is_full(); + */ +struct MyCircularQueue { + cap: usize, + start: usize, + end: usize, + len: usize, + data: Vec, +} + +/** + * `&self` means the method takes an immutable reference. + * If you need a mutable reference, change it to `&mut self` instead. + */ +impl MyCircularQueue { + fn new(k: i32) -> Self { + Self { + cap: k as usize, + len: 0, + start: 0, + end: 0, + data: vec![0; k as usize], + } + } + + fn en_queue(&mut self, value: i32) -> bool { + if self.is_full() { + return false; + } + self.len += 1; + self.data[self.start] = value; + + if self.start == self.cap - 1 { + self.start = 0; + } else { + self.start += 1; + } + + true + } + + fn de_queue(&mut self) -> bool { + if self.is_empty() { + return false; + } + + self.len -= 1; + + self.data[self.end] = 0; + + if self.end == self.cap - 1 { + self.end = 0; + } else { + self.end += 1; + } + + true + } + + fn front(&self) -> i32 { + if self.is_empty() { + return -1; + } + + self.data[self.end] + } + + fn rear(&self) -> i32 { + if self.is_empty() { + return -1; + } + + self.data[if self.start == 0 { + self.cap - 1 + } else { + self.start - 1 + }] + } + + fn is_empty(&self) -> bool { + self.len == 0 + } + + fn is_full(&self) -> bool { + self.len == self.cap + } +} diff --git a/src/bin/design-front-middle-back-queue.rs b/src/bin/design-front-middle-back-queue.rs new file mode 100644 index 00000000..2cba8e60 --- /dev/null +++ b/src/bin/design-front-middle-back-queue.rs @@ -0,0 +1,96 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +struct FrontMiddleBackQueue { + pre: std::collections::LinkedList, + back: std::collections::LinkedList, +} + +/** + * `&self` means the method takes an immutable reference. + * If you need a mutable reference, change it to `&mut self` instead. + */ +/** + * Your FrontMiddleBackQueue object will be instantiated and called as such: + * let obj = FrontMiddleBackQueue::new(); + * obj.push_front(val); + * obj.push_middle(val); + * obj.push_back(val); + * let ret_4: i32 = obj.pop_front(); + * let ret_5: i32 = obj.pop_middle(); + * let ret_6: i32 = obj.pop_back(); + */ +impl FrontMiddleBackQueue { + fn new() -> Self { + Self { + pre: std::collections::LinkedList::new(), + back: std::collections::LinkedList::new(), + } + } + + fn push_front(&mut self, val: i32) { + if self.pre.len() > self.back.len() { + if let Some(x) = self.pre.pop_back() { + self.back.push_front(x); + } + } + self.pre.push_front(val); + } + + fn push_middle(&mut self, val: i32) { + match self.pre.len() - self.back.len() { + 1 => { + if let Some(x) = self.pre.pop_back() { + self.back.push_front(x); + } + self.pre.push_back(val); + } + _ => self.pre.push_back(val), + } + } + + fn push_back(&mut self, val: i32) { + self.back.push_back(val); + if self.back.len() > self.pre.len() { + if let Some(x) = self.back.pop_front() { + self.pre.push_back(x); + } + } + } + + fn pop_front(&mut self) -> i32 { + if self.pre.len() == self.back.len() { + if let Some(x) = self.back.pop_front() { + self.pre.push_back(x); + } + } + + self.pre.pop_front().unwrap_or(-1) + } + + fn pop_middle(&mut self) -> i32 { + match self.pre.len() - self.back.len() { + 1 => self.pre.pop_back().unwrap_or(-1), + _ => { + let val = self.pre.pop_back().unwrap_or(-1); + if let Some(x) = self.back.pop_front() { + self.pre.push_back(x); + } + val + } + } + } + + fn pop_back(&mut self) -> i32 { + if self.pre.len() - self.back.len() > 0 { + if let Some(x) = self.pre.pop_back() { + self.back.push_front(x); + } + } + + self.back.pop_back().unwrap_or(-1) + } +} diff --git a/src/bin/design-hashmap.rs b/src/bin/design-hashmap.rs new file mode 100644 index 00000000..2cd75fb3 --- /dev/null +++ b/src/bin/design-hashmap.rs @@ -0,0 +1,82 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +/** + * `&self` means the method takes an immutable reference. + * If you need a mutable reference, change it to `&mut self` instead. + */ + +/** + * Your MyHashMap object will be instantiated and called as such: + * let obj = MyHashMap::new(); + * obj.put(key, value); + * let ret_2: i32 = obj.get(key); + * obj.remove(key); + */ + +struct Node { + key: i32, + value: i32, +} +struct MyHashMap { + array: Vec>, +} + +impl MyHashMap { + fn new() -> Self { + Self { + array: (0..1001) + .map(|_| std::collections::LinkedList::new()) + .collect(), + } + } + + fn put(&mut self, key: i32, value: i32) { + let index = key as usize / 1000; + let mut iter = self.array[index].iter_mut(); + + while let Some(n) = iter.next() { + if n.key == key { + n.value = value; + return; + } + } + + self.array[index].push_back(Node { key, value }); + } + + fn get(&self, key: i32) -> i32 { + let index = key as usize / 1000; + let mut iter = self.array[index].iter(); + + while let Some(n) = iter.next() { + if n.key == key { + return n.value; + } + } + + -1 + } + + fn remove(&mut self, key: i32) { + let index = key as usize / 1000; + let mut iter = self.array[index].iter(); + let mut x = None; + + for (i, n) in iter.enumerate() { + if n.key == key { + x = Some(i); + break; + } + } + + if let Some(x) = x { + let mut m = self.array[index].split_off(x); + m.pop_front(); + self.array[index].append(&mut m); + } + } +} diff --git a/src/bin/design-hashset.rs b/src/bin/design-hashset.rs new file mode 100644 index 00000000..76df8680 --- /dev/null +++ b/src/bin/design-hashset.rs @@ -0,0 +1,53 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +/** + * `&self` means the method takes an immutable reference. + * If you need a mutable reference, change it to `&mut self` instead. + */ + +/** + * Your MyHashSet object will be instantiated and called as such: + * let obj = MyHashSet::new(); + * obj.add(key); + * obj.remove(key); + * let ret_3: bool = obj.contains(key); + */ + +struct MyHashSet { + data: Box>, +} + +impl MyHashSet { + const S: u8 = 0b10000000; + + fn new() -> Self { + Self { + data: Box::new(vec![0; 10usize.pow(6u32) / 8 + 1]), + } + } + + fn add(&mut self, key: i32) { + let index1 = key as usize / 8; + let index2 = key as usize % 8; + + self.data[index1] |= Self::S >> index2; + } + + fn remove(&mut self, key: i32) { + let index1 = key as usize / 8; + let index2 = key as usize % 8; + + self.data[index1] &= !(Self::S >> index2); + } + + fn contains(&self, key: i32) -> bool { + let index1 = key as usize / 8; + let index2 = key as usize % 8; + + self.data[index1] & Self::S >> index2 != 0 + } +} diff --git a/src/bin/design-twitter.rs b/src/bin/design-twitter.rs new file mode 100644 index 00000000..229337aa --- /dev/null +++ b/src/bin/design-twitter.rs @@ -0,0 +1,97 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +#[derive(Default)] +struct User { + /// 关注者 + stars: std::collections::HashSet, + /// 时间与postid + posts: std::collections::LinkedList<(std::time::Instant, i32)>, +} + +struct Twitter { + users: std::collections::HashMap, +} + +/** +* `&self` means the method takes an immutable reference. +* If you need a mutable reference, change it to `&mut self` instead. + +* Your Twitter object will be instantiated and called as such: +* let obj = Twitter::new(); +* obj.post_tweet(userId, tweetId); +* let ret_2: Vec = obj.get_news_feed(userId); +* obj.follow(followerId, followeeId); +* obj.unfollow(followerId, followeeId); +*/ +impl Twitter { + fn new() -> Self { + Self { + users: std::collections::HashMap::new(), + } + } + + fn post_tweet(&mut self, user_id: i32, tweet_id: i32) { + let user = self.users.entry(user_id).or_insert_with(|| User::default()); + + if user.posts.len() == 10 { + user.posts.pop_back(); + } + + let now = std::time::Instant::now(); + + user.posts.push_front((now, tweet_id)); + } + + fn get_news_feed(&self, user_id: i32) -> Vec { + let user = if let Some(x) = self.users.get(&user_id) { + x + } else { + return vec![]; + }; + + let mut x = std::collections::BinaryHeap::new(); + + for i in user + .stars + .iter() + .map_while(|x| self.users.get(x)) + .flat_map(|x| x.posts.iter()) + .chain(user.posts.iter()) + { + x.push(std::cmp::Reverse(i.clone())); + + if x.len() == 11 { + x.pop(); + } + } + + let mut r = vec![0; x.len()]; + + while let Some(p) = x.pop() { + r[x.len()] = p.0 .1; + } + + r + } + + fn follow(&mut self, follower_id: i32, followee_id: i32) { + self.users + .entry(follower_id) + .or_insert_with(|| User::default()) + .stars + .insert(followee_id); + } + + fn unfollow(&mut self, follower_id: i32, followee_id: i32) { + self.users + .entry(follower_id) + .and_modify(|user| { + user.stars.remove(&followee_id); + }) + .or_insert_with(|| User::default()); + } +} diff --git a/src/bin/design-underground-system.rs b/src/bin/design-underground-system.rs new file mode 100644 index 00000000..75c97fd1 --- /dev/null +++ b/src/bin/design-underground-system.rs @@ -0,0 +1,55 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +struct UndergroundSystem { + /// 乘客进站的时间记录 + check_in: std::collections::HashMap, + + /// 记录站到站花费的总时间和总人次 + station: std::collections::HashMap<(String, String), (i32, i32)>, +} + +// /** +// * `&self` means the method takes an immutable reference. +// * If you need a mutable reference, change it to `&mut self` instead. +// */ +impl UndergroundSystem { + fn new() -> Self { + Self { + check_in: Default::default(), + station: Default::default(), + } + } + + fn check_in(&mut self, id: i32, station_name: String, t: i32) { + self.check_in.insert(id, (station_name, t)); + } + + fn check_out(&mut self, id: i32, station_name: String, t: i32) { + let (start_station, start) = self.check_in.remove(&id).unwrap(); + self.station + .entry((start_station, station_name)) + .and_modify(|x| { + x.0 += t - start; + x.1 += 1; + }) + .or_insert((t - start, 1)); + } + + fn get_average_time(&self, start_station: String, end_station: String) -> f64 { + let x = self.station.get(&(start_station, end_station)).unwrap(); + + x.0 as f64 / x.1 as f64 + } +} + +// /** +// * Your UndergroundSystem object will be instantiated and called as such: +// * let obj = UndergroundSystem::new(); +// * obj.check_in(id, stationName, t); +// * obj.check_out(id, stationName, t); +// * let ret_3: f64 = obj.get_average_time(startStation, endStation); +// */ diff --git a/src/bin/detect-capital.rs b/src/bin/detect-capital.rs new file mode 100644 index 00000000..54d80216 --- /dev/null +++ b/src/bin/detect-capital.rs @@ -0,0 +1,30 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn detect_capital_use(word: String) -> bool { + let mut flag = false; + + for (i, &v) in word.as_bytes().iter().enumerate() { + if i == 0 && v >= b'A' && v <= b'Z' { + flag = true; + } else { + if v >= b'A' && v <= b'Z' { + if !flag { + return false; + } + } else { + if flag && i != 1 { + return false; + } + flag = false; + } + } + } + + true + } +} diff --git a/src/bin/detect-pattern-of-length-m-repeated-k-or-more-times.rs b/src/bin/detect-pattern-of-length-m-repeated-k-or-more-times.rs new file mode 100644 index 00000000..6c603be5 --- /dev/null +++ b/src/bin/detect-pattern-of-length-m-repeated-k-or-more-times.rs @@ -0,0 +1,29 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn contains_pattern(arr: Vec, m: i32, k: i32) -> bool { + if (arr.len() as i32) < m * k { + return false; + } + + 'l: for i in 0..arr.len() - (m as usize) { + for j in i..m as usize + i { + for v in 0..k as usize { + match arr.get(j + v * m as usize) { + Some(&x) if x != arr[j] => continue 'l, + None => continue 'l, + _ => {} + } + } + } + + return true; + } + + false + } +} diff --git a/src/bin/determine-if-two-strings-are-close.rs b/src/bin/determine-if-two-strings-are-close.rs new file mode 100644 index 00000000..e0015507 --- /dev/null +++ b/src/bin/determine-if-two-strings-are-close.rs @@ -0,0 +1,37 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn close_strings(word1: String, word2: String) -> bool { + if word1.len() != word2.len() { + return false; + } + let (mut h1, mut h2) = ([0; 26], [0; 26]); + for i in 0..word1.len() { + h1[(word1.as_bytes()[i] - b'a') as usize] += 1; + h2[(word2.as_bytes()[i] - b'a') as usize] += 1; + } + + for i in 0..26 { + match (h1[i], h2[i]) { + (0, 0) => continue, + (0, _) | (_, 0) => return false, + _ => continue, + } + } + + h1.sort(); + h2.sort(); + + for i in 0..h1.len() { + if h1[i] != h2[i] { + return false; + } + } + + true + } +} diff --git a/src/bin/determine-the-winner-of-a-bowling-game.rs b/src/bin/determine-the-winner-of-a-bowling-game.rs new file mode 100644 index 00000000..733b5e90 --- /dev/null +++ b/src/bin/determine-the-winner-of-a-bowling-game.rs @@ -0,0 +1,40 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn is_winner(player1: Vec, player2: Vec) -> i32 { + let (mut r, mut j) = (0, 0); + + for i in 0..player1.len() { + if i == 1 { + if player1[0] == 10 { + r += player1[i]; + } + if player2[0] == 10 { + j += player2[i]; + } + } else if i > 1 { + if player1[i - 1] == 10 || player1[i - 2] == 10 { + r += player1[i]; + } + if player2[i - 1] == 10 || player2[i - 2] == 10 { + j += player2[i]; + } + } + + r += player1[i]; + j += player2[i]; + } + + if r > j { + 1 + } else if j > r { + 2 + } else { + 0 + } + } +} diff --git a/src/bin/di-string-match.rs b/src/bin/di-string-match.rs new file mode 100644 index 00000000..d1ed5820 --- /dev/null +++ b/src/bin/di-string-match.rs @@ -0,0 +1,26 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn di_string_match(s: String) -> Vec { + let mut v = Vec::with_capacity(s.len() + 1); + let (mut m, mut n) = (0, s.len() as i32); + + for &i in s.as_bytes().into_iter() { + if i == b'I' { + v.push(m); + m += 1; + } else { + v.push(n); + n -= 1; + } + } + + v.push(m); + + v + } +} diff --git a/src/bin/di-yi-ge-zhi-chu-xian-yi-ci-de-zi-fu-lcof.rs b/src/bin/di-yi-ge-zhi-chu-xian-yi-ci-de-zi-fu-lcof.rs new file mode 100644 index 00000000..94d495af --- /dev/null +++ b/src/bin/di-yi-ge-zhi-chu-xian-yi-ci-de-zi-fu-lcof.rs @@ -0,0 +1,50 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + /// 通过HashMap + pub fn first_uniq_char(s: String) -> char { + if s == "".to_string() { + return ' '; + } + + let mut m = std::collections::HashMap::new(); + for &i in s.as_bytes() { + m.entry(i).and_modify(|x| *x += 1).or_insert(1); + } + + for &i in s.as_bytes() { + if let Some(s) = m.get(&i) { + if *s == 1 { + return i as char; + } + } + } + + ' ' + } + + /// 通过数组 + pub fn first_uniq_char1(s: String) -> char { + if s == "".to_string() { + return ' '; + } + + let mut a = [0; 26]; + + for &i in s.as_bytes() { + a[(i - 97) as usize] += 1; + } + + for &i in s.as_bytes() { + if a[(i - 97) as usize] == 1 { + return i as char; + } + } + + ' ' + } +} diff --git a/src/bin/diameter-of-binary-tree.rs b/src/bin/diameter-of-binary-tree.rs new file mode 100644 index 00000000..60877ef4 --- /dev/null +++ b/src/bin/diameter-of-binary-tree.rs @@ -0,0 +1,49 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +// Definition for a binary tree node. +#[derive(Debug, PartialEq, Eq)] +pub struct TreeNode { + pub val: i32, + pub left: Option>>, + pub right: Option>>, +} + +impl TreeNode { + #[inline] + pub fn new(val: i32) -> Self { + TreeNode { + val, + left: None, + right: None, + } + } +} + +use std::cell::RefCell; +use std::rc::Rc; +impl Solution { + /// 左边的最深度 + 右边的最深度 + pub fn diameter_of_binary_tree(root: Option>>) -> i32 { + let (_, r) = Self::height(root); + r + } + + /// 返回深度和对应节点上的最大直径 + pub fn height(root: Option>>) -> (i32, i32) { + if root.is_none() { + return (0, 0); + } + + let (left, max_left) = Self::height(root.clone().unwrap().borrow().left.clone()); + let (right, max_right) = Self::height(root.clone().unwrap().borrow().right.clone()); + + ( + left.max(right) + 1, + (left + right).max(max_left).max(max_right), + ) + } +} diff --git a/src/bin/diao-zheng-shu-zu-shun-xu-shi-qi-shu-wei-yu-ou-shu-qian-mian-lcof.rs b/src/bin/diao-zheng-shu-zu-shun-xu-shi-qi-shu-wei-yu-ou-shu-qian-mian-lcof.rs new file mode 100644 index 00000000..71757f72 --- /dev/null +++ b/src/bin/diao-zheng-shu-zu-shun-xu-shi-qi-shu-wei-yu-ou-shu-qian-mian-lcof.rs @@ -0,0 +1,29 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn exchange(nums: Vec) -> Vec { + if nums.is_empty() { + return vec![]; + } + + let mut nums = nums; + let (mut start, mut end) = (0, nums.len() - 1); + + while start < end { + while start < end && nums[start] % 2 == 1 { + start += 1; + } + while start < end && nums[end] % 2 == 0 { + end -= 1; + } + + nums.swap(start, end); + } + + nums + } +} diff --git a/src/bin/difference-between-element-sum-and-digit-sum-of-an-array.rs b/src/bin/difference-between-element-sum-and-digit-sum-of-an-array.rs new file mode 100644 index 00000000..0e3cd707 --- /dev/null +++ b/src/bin/difference-between-element-sum-and-digit-sum-of-an-array.rs @@ -0,0 +1,22 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn difference_of_sum(nums: Vec) -> i32 { + let (mut a1, mut a2) = (0, 0); + + for mut i in nums { + a1 += i; + + while i > 0 { + a2 += i % 10; + i /= 10; + } + } + + (a1 - a2).abs() + } +} diff --git a/src/bin/distance-between-bus-stops.rs b/src/bin/distance-between-bus-stops.rs new file mode 100644 index 00000000..e1a31e17 --- /dev/null +++ b/src/bin/distance-between-bus-stops.rs @@ -0,0 +1,45 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn distance_between_bus_stops(distance: Vec, start: i32, destination: i32) -> i32 { + let (mut sum1, mut sum2) = (0, 0); + + let mut start1 = start as usize; + loop { + if start1 == destination as usize { + break; + } + if start1 == distance.len() - 1 { + sum1 += distance[start1]; + start1 = 0; + } else { + sum1 += distance[start1]; + start1 += 1; + } + } + + let mut start2 = start as usize; + loop { + if start2 == destination as usize { + break; + } + + if start2 == 0 { + sum2 += distance[distance.len() - 1]; + start2 = distance.len() - 1; + } else { + sum2 += distance[start2 - 1]; + start2 -= 1; + } + } + + if sum1 < sum2 { + return sum1; + } + sum2 + } +} diff --git a/src/bin/distinct-subsequences-ii.rs b/src/bin/distinct-subsequences-ii.rs new file mode 100644 index 00000000..7f588987 --- /dev/null +++ b/src/bin/distinct-subsequences-ii.rs @@ -0,0 +1,35 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() { + assert_eq!(Solution::distinct_subseq_ii("abc".into()), 7); + assert_eq!(Solution::distinct_subseq_ii("aaa".into()), 3); +} + +struct Solution; + +impl Solution { + /// 暴力解法 + /// 从长度为1开始, + /// 从下标为0开始 + /// + /// dp + /// v[i]表示s[0..i]的子串个数 + /// 则v[i] = v[i-1] + 新增个数a - 重复个数b + /// 因为s[0..i]相较于s[0..i-1]新增了一个字符,所以 a = v[i-1]+1 + /// 新增的子串都是以s[i]结尾的,所以重复的肯定是上次遇到相同字符结尾的字符串子串的个数,因此记录下每个字符上次出现的个数,即为重复的个数 + pub fn distinct_subseq_ii(s: String) -> i32 { + // let mut v = vec![0; s.len()]; // 这种只需要前一个数据,不需要回溯的,用一个变量表示就行了 + let mut repeate = [0; 26]; + let bytes = s.as_bytes(); + + let mut v = 1; + repeate[(bytes[0] - b'a') as usize] = v; + + for i in 1..bytes.len() { + v = (v * 2 + 1) - repeate[(bytes[i] - b'a') as usize]; + repeate[(bytes[i] - b'a') as usize] = v; + } + + v + } +} diff --git a/src/bin/distribute-candies-among-children-i.rs b/src/bin/distribute-candies-among-children-i.rs new file mode 100644 index 00000000..387e7e64 --- /dev/null +++ b/src/bin/distribute-candies-among-children-i.rs @@ -0,0 +1,12 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn distribute_candies(n: i32, limit: i32) -> i32 { + let c2 = |n| if n > 1 { n * (n - 1) / 2 } else { 0 }; + c2(n + 2) - 3 * c2(n - limit + 1) + 3 * c2(n - 2 * limit) - c2(n - 3 * limit - 1) + } +} diff --git a/src/bin/distribute-candies-to-people.rs b/src/bin/distribute-candies-to-people.rs new file mode 100644 index 00000000..7d4db85d --- /dev/null +++ b/src/bin/distribute-candies-to-people.rs @@ -0,0 +1,21 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn distribute_candies(candies: i32, num_people: i32) -> Vec { + let m = (((8.0 * candies as f64 + 1.0).sqrt() - 1.0) / 2.0) as i32; + let k = m / num_people; + let extra = m % num_people; + let mut ans = (0..num_people) + .map(|i| { + let k = if i < extra { k + 1 } else { k }; + k * (k - 1) / 2 * num_people + k * (i + 1) + }) + .collect::>(); + ans[extra as usize] += candies - m * (m + 1) / 2; + ans + } +} diff --git a/src/bin/distribute-candies.rs b/src/bin/distribute-candies.rs new file mode 100644 index 00000000..f3529201 --- /dev/null +++ b/src/bin/distribute-candies.rs @@ -0,0 +1,13 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn distribute_candies(candy_type: Vec) -> i32 { + use std::collections::HashSet; + let set = candy_type.iter().collect::>(); + set.len().min(candy_type.len() / 2) as _ + } +} diff --git a/src/bin/distribute-coins-in-binary-tree.rs b/src/bin/distribute-coins-in-binary-tree.rs new file mode 100644 index 00000000..3c77ddef --- /dev/null +++ b/src/bin/distribute-coins-in-binary-tree.rs @@ -0,0 +1,35 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +// Definition for a binary tree node. +#[derive(Debug, PartialEq, Eq)] +pub struct TreeNode { + pub val: i32, + pub left: Option>>, + pub right: Option>>, +} + +impl TreeNode { + #[inline] + pub fn new(val: i32) -> Self { + TreeNode { + val, + left: None, + right: None, + } + } +} + +use std::cell::RefCell; +use std::rc::Rc; + +impl Solution { + pub fn distribute_coins(root: Option>>) -> i32 { + let mut r = 0; + + r + } +} diff --git a/src/bin/distribute-elements-into-two-arrays-i.rs b/src/bin/distribute-elements-into-two-arrays-i.rs new file mode 100644 index 00000000..bd552309 --- /dev/null +++ b/src/bin/distribute-elements-into-two-arrays-i.rs @@ -0,0 +1,27 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn result_array(nums: Vec) -> Vec { + let mut nums1 = Vec::with_capacity(nums.len()); + let mut nums2 = vec![]; + + nums1.push(nums[0]); + nums2.push(nums[1]); + + for i in 2..nums.len() { + if nums1[nums1.len() - 1] > nums2[nums2.len() - 1] { + nums1.push(nums[i]); + } else { + nums2.push(nums[i]); + } + } + + nums1.extend(nums2); + + nums1 + } +} diff --git a/src/bin/distribute-money-to-maximum-children.rs b/src/bin/distribute-money-to-maximum-children.rs new file mode 100644 index 00000000..59fa4a41 --- /dev/null +++ b/src/bin/distribute-money-to-maximum-children.rs @@ -0,0 +1,33 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn dist_money(money: i32, children: i32) -> i32 { + if money < children { + return -1; + } + let money = money - children; // 先给个孩子都分一块钱 + let s = children * 7; + + if s == money { + // 剩下的钱刚好每人7块 + children + } else if s < money { + // 剩下的钱大于每人7块,那有个孩子获得每人7块后余下的钱 + children - 1 + } else { + let mut cnt = children.min(money / 7); + let money = money - cnt * 7; + let children = children - cnt; + + if (children == 0 && money > 0) || (children == 1 && money == 3) { + cnt -= 1; + } + + cnt + } + } +} diff --git a/src/bin/divide-array-into-arrays-with-max-difference.rs b/src/bin/divide-array-into-arrays-with-max-difference.rs new file mode 100644 index 00000000..4755ec9f --- /dev/null +++ b/src/bin/divide-array-into-arrays-with-max-difference.rs @@ -0,0 +1,24 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn divide_array(nums: Vec, k: i32) -> Vec> { + let mut nums = nums; + nums.sort(); + + let mut result = vec![]; + + for i in (2..nums.len()).step_by(3) { + if nums[i] - nums[i - 2] > k { + return vec![]; + } + + result.push(vec![nums[i], nums[i - 1], nums[i - 2]]); + } + + result + } +} diff --git a/src/bin/divide-two-integers.rs b/src/bin/divide-two-integers.rs new file mode 100644 index 00000000..c3599aa5 --- /dev/null +++ b/src/bin/divide-two-integers.rs @@ -0,0 +1,50 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() { + assert_eq!(Solution::divide(10, 3), 3); + assert_eq!(Solution::divide(7, -3), -2); +} + +struct Solution; + +impl Solution { + // 设 x 为被除数,y为除数, z 为结果 + // 如果 x > y + y, 则 z+=z,y += y + // 如果 x < y + y, 则 x -= y, 返回步骤二继续计算剩余的数 + pub fn divide(dividend: i32, divisor: i32) -> i32 { + let ans = Self::d(dividend as i64, divisor as i64); + if ans > i32::MAX as i64 { + i32::MAX + } else if ans < i32::MIN as i64 { + i32::MIN + } else { + ans as i32 + } + } + + pub fn d(dividend: i64, divisor: i64) -> i64 { + // 符号位, true表示为正数 + let is_na = dividend.signum() == divisor.signum(); + + let (mut dividend, divisor) = (dividend.abs(), divisor.abs()); + + if dividend < divisor { + return 0; + } + + let mut start = divisor; + let mut ans = 1; + while dividend > start + start { + ans += ans; + start += start; + } + + ans += Self::d(dividend - start, divisor); + + if !is_na { + ans = 0 - ans; + } + + ans + } +} diff --git a/src/bin/diving-board-lcci.rs b/src/bin/diving-board-lcci.rs new file mode 100644 index 00000000..91f6529f --- /dev/null +++ b/src/bin/diving-board-lcci.rs @@ -0,0 +1,27 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn diving_board(shorter: i32, longer: i32, k: i32) -> Vec { + let mut v = Vec::::new(); + if k == 0 { + return v; + } + + if shorter == longer { + v.push(shorter * k); + return v; + } + + for i in 0..=k { + let s = i * longer + (k - i) * shorter; + + v.push(s); + } + + v + } +} diff --git a/src/bin/dota2-senate.rs b/src/bin/dota2-senate.rs new file mode 100644 index 00000000..ae3cc335 --- /dev/null +++ b/src/bin/dota2-senate.rs @@ -0,0 +1,56 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + assert_eq!( + "Dire".to_string(), + Solution::predict_party_victory("DDRRR".to_string()) + ); +} + +struct Solution; + +impl Solution { + pub fn predict_party_victory(senate: String) -> String { + let mut senate = senate + .as_bytes() + .into_iter() + .map(|x| *x) + .collect::>(); + + let (mut r_ban, mut d_ban) = (0, 0); + + loop { + let (mut r_num, mut d_num) = (0, 0); + for i in 0..senate.len() { + if senate[i] == b'x' { + continue; + } + if senate[i] == b'R' { + if r_ban > 0 { + r_ban -= 1; + senate[i] = b'x'; + } else { + d_ban += 1; + r_num += 1; + } + } else { + if d_ban > 0 { + d_ban -= 1; + senate[i] = b'x'; + } else { + r_ban += 1; + d_num += 1; + } + } + } + + if r_num == 0 { + return "Dire".to_string(); + } + + if d_num == 0 { + return "Radiant".to_string(); + } + } + } +} diff --git a/src/bin/double-modular-exponentiation.rs b/src/bin/double-modular-exponentiation.rs new file mode 100644 index 00000000..10b623db --- /dev/null +++ b/src/bin/double-modular-exponentiation.rs @@ -0,0 +1,35 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn get_good_indices(variables: Vec>, target: i32) -> Vec { + variables + .into_iter() + .enumerate() + .filter_map(|(x, y)| { + if (Self::pow(Self::pow(y[0], y[1], 10), y[2], y[3])) == target { + Some(x as i32) + } else { + None + } + }) + .collect() + } + + fn pow(mut x: i32, mut y: i32, z: i32) -> i32 { + let mut result = 1; + while y > 0 { + if y % 2 > 0 { + result = result * x % z; + } + + x = x * x % z; + y /= 2; + } + + result + } +} diff --git a/src/bin/dui-cheng-de-er-cha-shu-lcof.rs b/src/bin/dui-cheng-de-er-cha-shu-lcof.rs new file mode 100644 index 00000000..62939b36 --- /dev/null +++ b/src/bin/dui-cheng-de-er-cha-shu-lcof.rs @@ -0,0 +1,59 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +// Definition for a binary tree node. +#[derive(Debug, PartialEq, Eq)] +pub struct TreeNode { + pub val: i32, + pub left: Option>>, + pub right: Option>>, +} + +impl TreeNode { + #[inline] + pub fn new(val: i32) -> Self { + TreeNode { + val, + left: None, + right: None, + } + } +} +use std::cell::RefCell; +use std::ops::Index; +use std::rc::Rc; +impl Solution { + pub fn is_symmetric(root: Option>>) -> bool { + if root.is_none() { + return true; + } + + let left = root.as_ref().unwrap().borrow_mut().left.take(); + let right = root.as_ref().unwrap().borrow_mut().right.take(); + + let mut v = vec![left, right]; + let (mut i, mut j) = (0, 1); + + while !v.is_empty() { + match (v.pop(), v.pop()) { + (Some(Some(x)), Some(Some(y))) => { + if x.borrow().val != y.borrow().val { + return false; + } + + v.push(x.borrow_mut().left.take()); + v.push(y.borrow_mut().right.take()); + v.push(x.borrow_mut().right.take()); + v.push(y.borrow_mut().left.take()); + } + (Some(None), Some(None)) => {} + _ => return false, + } + } + + true + } +} diff --git a/src/bin/dui-lie-de-zui-da-zhi-lcof.rs b/src/bin/dui-lie-de-zui-da-zhi-lcof.rs new file mode 100644 index 00000000..d0f7e526 --- /dev/null +++ b/src/bin/dui-lie-de-zui-da-zhi-lcof.rs @@ -0,0 +1,63 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +struct MaxQueue { + queue: Vec, + deque: Vec, +} + +/** + * `&self` means the method takes an immutable reference. + * If you need a mutable reference, change it to `&mut self` instead. + */ +impl MaxQueue { + fn new() -> Self { + MaxQueue { + queue: vec![], + deque: vec![], + } + } + + fn max_value(&self) -> i32 { + self.deque.first().map(|x| *x).unwrap_or(-1) + } + + fn push_back(&mut self, value: i32) { + while !self.deque.is_empty() { + if self.deque[self.deque.len() - 1] >= value { + break; + } + + self.deque.pop(); + } + + self.deque.push(value); + self.queue.push(value); + } + + fn pop_front(&mut self) -> i32 { + if self.deque.is_empty() { + return -1; + } + + let v = self.queue[0]; + self.queue = self.queue[1..].to_vec(); + + if v == self.deque[0] { + self.deque = self.deque[1..].to_vec(); + } + + v + } +} + +// /** +// * Your MaxQueue object will be instantiated and called as such: +// * let obj = MaxQueue::new(); +// * let ret_1: i32 = obj.max_value(); +// * obj.push_back(value); +// * let ret_3: i32 = obj.pop_front(); +// */ diff --git a/src/bin/duplicate-zeros.rs b/src/bin/duplicate-zeros.rs new file mode 100644 index 00000000..4250cac8 --- /dev/null +++ b/src/bin/duplicate-zeros.rs @@ -0,0 +1,41 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + /// 有多少个零重复,后面就会被截断多少 + /// 然后从截断开始的位置往前回放,遇到0就放2两个就行了。 + pub fn duplicate_zeros(arr: &mut Vec) { + let (mut i, mut j) = (0, 0); + while j <= arr.len() - 1 { + if arr[i] == 0 { + j += 1; + } + j += 1; + i += 1; + } + + j -= 1; + i -= 1; + + while i >= 0 { + if j < arr.len() { + arr[j] = arr[i]; + } + + if arr[i] == 0 { + j -= 1; + arr[j] = 0; + } + + if i == 0 { + return; + } + + j -= 1; + i -= 1; + } + } +} diff --git a/src/bin/edit-distance.rs b/src/bin/edit-distance.rs new file mode 100644 index 00000000..1e3bfc35 --- /dev/null +++ b/src/bin/edit-distance.rs @@ -0,0 +1,39 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() { + assert_eq!(Solution::min_distance("horse".into(), "ros".into()), 3); +} + +struct Solution; + +impl Solution { + pub fn min_distance(word1: String, word2: String) -> i32 { + let m = word1.len(); + let n = word2.len(); + + let (b1, b2) = (word1.as_bytes(), word2.as_bytes()); + + let mut d = vec![vec![0; n + 1]; m + 1]; + + for i in 1..=n { + d[0][i] = d[0][i - 1] + 1; + } + + for i in 1..=m { + d[i][0] = d[i - 1][0] + 1; + } + + for i in 1..=m { + for j in 1..=n { + let mut l = d[i - 1][j - 1]; + if b1[i - 1] == b2[j - 1] { + l -= 1; + } + + d[i][j] = d[i][j - 1].min(l).min(d[i - 1][j]) + 1; + } + } + + d[m][n] + } +} diff --git a/src/bin/eliminate-maximum-number-of-monsters.rs b/src/bin/eliminate-maximum-number-of-monsters.rs new file mode 100644 index 00000000..2038564e --- /dev/null +++ b/src/bin/eliminate-maximum-number-of-monsters.rs @@ -0,0 +1,29 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn eliminate_maximum(dist: Vec, speed: Vec) -> i32 { + let mut s: Vec<_> = dist + .into_iter() + .zip(speed) + .map(|(x, y)| if x % y == 0 { x / y } else { x / y + 1 }) + .collect(); + + s.sort(); + + let mut r = 1; + + for i in 0..s.len() - 1 { + if i as i32 + 1 >= s[i] && s[i] == s[i + 1] { + break; + } + + r += 1; + } + + r + } +} diff --git a/src/bin/encode-and-decode-tinyurl.rs b/src/bin/encode-and-decode-tinyurl.rs new file mode 100644 index 00000000..be56aeb2 --- /dev/null +++ b/src/bin/encode-and-decode-tinyurl.rs @@ -0,0 +1,46 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +/** + * Your Codec object will be instantiated and called as such: + * let obj = Codec::new(); + * let s: String = obj.encode(strs); + * let ans: VecVec = obj.decode(s); + */ +struct Codec { + hash: std::collections::HashMap, +} + +/** + * `&self` means the method takes an immutable reference. + * If you need a mutable reference, change it to `&mut self` instead. + */ +impl Codec { + fn new() -> Self { + Self { + hash: std::collections::HashMap::new(), + } + } + + // Encodes a URL to a shortened URL. + fn encode(&mut self, long_url: String) -> String { + let mut s = std::collections::hash_map::DefaultHasher::new(); + ::hash(&long_url, &mut s); + let hash_code = + ::finish(&s); + self.hash.insert(hash_code, long_url); + format!("http://tinyurl.com/{}", hash_code) + } + + // Decodes a shortened URL to its original URL. + fn decode(&self, short_url: String) -> String { + let hash_code = short_url + .trim_start_matches("http://tinyurl.com/") + .parse::() + .unwrap(); + self.hash.get(&hash_code).unwrap().to_string() + } +} diff --git a/src/bin/er-cha-shu-de-jing-xiang-lcof.rs b/src/bin/er-cha-shu-de-jing-xiang-lcof.rs new file mode 100644 index 00000000..ce281a01 --- /dev/null +++ b/src/bin/er-cha-shu-de-jing-xiang-lcof.rs @@ -0,0 +1,41 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +// Definition for a binary tree node. +#[derive(Debug, PartialEq, Eq)] +pub struct TreeNode { + pub val: i32, + pub left: Option>>, + pub right: Option>>, +} + +impl TreeNode { + #[inline] + pub fn new(val: i32) -> Self { + TreeNode { + val, + left: None, + right: None, + } + } +} +use std::cell::RefCell; +use std::rc::Rc; +impl Solution { + pub fn mirror_tree(root: Option>>) -> Option>> { + if root.is_none() { + return None; + } + + let left = Self::mirror_tree(root.as_ref().unwrap().borrow_mut().right.take()); + let right = Self::mirror_tree(root.as_ref().unwrap().borrow_mut().left.take()); + + root.as_ref().unwrap().borrow_mut().left = left; + root.as_ref().unwrap().borrow_mut().right = right; + + root + } +} diff --git a/src/bin/er-cha-shu-de-shen-du-lcof.rs b/src/bin/er-cha-shu-de-shen-du-lcof.rs new file mode 100644 index 00000000..f11099f0 --- /dev/null +++ b/src/bin/er-cha-shu-de-shen-du-lcof.rs @@ -0,0 +1,71 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +// Definition for a binary tree node. +#[derive(Debug, PartialEq, Eq)] +pub struct TreeNode { + pub val: i32, + pub left: Option>>, + pub right: Option>>, +} + +impl TreeNode { + #[inline] + pub fn new(val: i32) -> Self { + TreeNode { + val, + left: None, + right: None, + } + } +} + +use std::cell::RefCell; +use std::rc::Rc; + +use serde::__private::de; +impl Solution { + pub fn max_depth1(root: Option>>) -> i32 { + if root.is_none() { + return 0; + } + + let mut depth = 0; + let mut v = vec![root]; + + while !v.is_empty() { + let mut new_v = vec![]; + + while let Some(Some(x)) = v.pop() { + let left = x.borrow_mut().left.take(); + if left.is_some() { + new_v.push(left); + } + + let right = x.borrow_mut().right.take(); + if right.is_some() { + new_v.push(right); + } + } + + depth += 1; + v = new_v; + } + + depth + } + + pub fn max_depth(root: Option>>) -> i32 { + if root.is_none() { + return 0; + } + + let left = root.clone().unwrap().borrow_mut().left.take(); + let right = root.clone().unwrap().borrow_mut().right.take(); + + 1 + Self::max_depth(left).max(Self::max_depth(right)) + } +} diff --git a/src/bin/er-cha-shu-zhong-he-wei-mou-yi-zhi-de-lu-jing-lcof.rs b/src/bin/er-cha-shu-zhong-he-wei-mou-yi-zhi-de-lu-jing-lcof.rs new file mode 100644 index 00000000..c261e872 --- /dev/null +++ b/src/bin/er-cha-shu-zhong-he-wei-mou-yi-zhi-de-lu-jing-lcof.rs @@ -0,0 +1,62 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +// Definition for a binary tree node. +#[derive(Debug, PartialEq, Eq)] +pub struct TreeNode { + pub val: i32, + pub left: Option>>, + pub right: Option>>, +} + +impl TreeNode { + #[inline] + pub fn new(val: i32) -> Self { + TreeNode { + val, + left: None, + right: None, + } + } +} +use std::cell::RefCell; +use std::rc::Rc; +use std::vec; +impl Solution { + pub fn path_sum(root: Option>>, target: i32) -> Vec> { + if root.is_none() { + return vec![]; + } + + let root = root.unwrap(); + let val = root.borrow().val; + let left = root.borrow_mut().left.take(); + let right = root.borrow_mut().right.take(); + + if val == target && left.is_none() && right.is_none() { + return vec![vec![val]]; + } + + let v1 = Self::path_sum(left, target - val); + let v2 = Self::path_sum(right, target - val); + + let mut data = vec![]; + + for i in v1 { + let mut v = vec![val]; + v.extend(i); + data.push(v); + } + + for i in v2 { + let mut v = vec![val]; + v.extend(i); + data.push(v); + } + + data + } +} diff --git a/src/bin/er-cha-sou-suo-shu-de-di-kda-jie-dian-lcof.rs b/src/bin/er-cha-sou-suo-shu-de-di-kda-jie-dian-lcof.rs new file mode 100644 index 00000000..b4200298 --- /dev/null +++ b/src/bin/er-cha-sou-suo-shu-de-di-kda-jie-dian-lcof.rs @@ -0,0 +1,57 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +// Definition for a binary tree node. +#[derive(Debug, PartialEq, Eq)] +pub struct TreeNode { + pub val: i32, + pub left: Option>>, + pub right: Option>>, +} + +impl TreeNode { + #[inline] + pub fn new(val: i32) -> Self { + TreeNode { + val, + left: None, + right: None, + } + } +} + +use std::cell::RefCell; +use std::rc::Rc; + +impl Solution { + pub fn kth_largest(root: Option>>, k: i32) -> i32 { + if k == 0 { + return root.unwrap().borrow().val; + } + let mut v = Vec::::new(); + Self::scan(root, &mut v, k as usize); + + v[k as usize - 1] + } + + fn scan(root: Option>>, val: &mut Vec, k: usize) { + let root = root.unwrap(); + if RefCell::borrow(&root).right.is_some() { + let right = root.borrow_mut().right.take(); + Self::scan(right, val, k); + } + + val.push(root.borrow().val); + if val.len() == k { + return; + } + + if RefCell::borrow(&root).left.is_some() { + let right = root.borrow_mut().left.take(); + Self::scan(right, val, k); + } + } +} diff --git a/src/bin/er-cha-sou-suo-shu-de-hou-xu-bian-li-xu-lie-lcof.rs b/src/bin/er-cha-sou-suo-shu-de-hou-xu-bian-li-xu-lie-lcof.rs new file mode 100644 index 00000000..98a1a5fd --- /dev/null +++ b/src/bin/er-cha-sou-suo-shu-de-hou-xu-bian-li-xu-lie-lcof.rs @@ -0,0 +1,36 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() { + assert!(!Solution::verify_postorder(vec![1, 6, 3, 2, 5])); + assert!(Solution::verify_postorder(vec![1, 3, 2, 6, 5])); + assert!(Solution::verify_postorder(vec![4, 8, 6, 12, 16, 14, 10])); + assert!(Solution::verify_postorder(vec![5, 4, 3, 2, 1])); +} + +struct Solution; + +impl Solution { + pub fn verify_postorder(postorder: Vec) -> bool { + Self::recurse(&postorder[..]) + } + + pub fn recurse(postorder: &[i32]) -> bool { + if postorder.is_empty() { + return true; + } + + let mut p = 0; + while p < postorder.len() && postorder[p] < postorder[postorder.len() - 1] { + p += 1; + } + + let mut q = p; + while q < postorder.len() && postorder[q] > postorder[postorder.len() - 1] { + q += 1; + } + + postorder[0..p].len() + postorder[p..q].len() + 1 == postorder.len() + && Self::recurse(&postorder[0..p]) + && Self::recurse(&postorder[p..q]) + } +} diff --git a/src/bin/er-jin-zhi-zhong-1de-ge-shu-lcof.rs b/src/bin/er-jin-zhi-zhong-1de-ge-shu-lcof.rs new file mode 100644 index 00000000..c29205ad --- /dev/null +++ b/src/bin/er-jin-zhi-zhong-1de-ge-shu-lcof.rs @@ -0,0 +1,30 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() { + assert_eq!( + Solution::hammingWeight(0b11111111111111111111111111111101), + 31 + ); + assert_eq!( + Solution::hammingWeight(0b00000000000000000000000000001011), + 3 + ); +} + +struct Solution; + +impl Solution { + fn hammingWeight(mut num: u32) -> i32 { + let mut s = 0; + + while num > 0 { + if num & 1 == 1 { + s += 1; + } + + num >>= 1; + } + + s + } +} diff --git a/src/bin/er-wei-shu-zu-zhong-de-cha-zhao-lcof.rs b/src/bin/er-wei-shu-zu-zhong-de-cha-zhao-lcof.rs new file mode 100644 index 00000000..755f28a3 --- /dev/null +++ b/src/bin/er-wei-shu-zu-zhong-de-cha-zhao-lcof.rs @@ -0,0 +1,37 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn find_number_in2_d_array(matrix: Vec>, target: i32) -> bool { + if matrix.is_empty() || matrix[0].is_empty() { + return false; + } + + let (mut i, mut j) = (matrix.len() - 1, 0); + + loop { + match target.cmp(&matrix[i][j]) { + std::cmp::Ordering::Equal => return true, + std::cmp::Ordering::Greater => { + if j == matrix[0].len() - 1 { + return false; + } + + j += 1; + } + std::cmp::Ordering::Less => { + if i == 0 { + return false; + } + + i -= 1; + } + } + } + + false + } +} diff --git a/src/bin/evaluate-reverse-polish-notation.rs b/src/bin/evaluate-reverse-polish-notation.rs new file mode 100644 index 00000000..94c913e0 --- /dev/null +++ b/src/bin/evaluate-reverse-polish-notation.rs @@ -0,0 +1,30 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn eval_rpn(tokens: Vec) -> i32 { + let mut v = vec![]; + + for i in tokens.into_iter() { + if let Ok(i) = i.parse::() { + v.push(i); + } else { + let (x1, x2) = (v.pop().unwrap(), v.pop().unwrap()); + + let x = match i.as_str() { + "+" => x1 + x2, + "-" => x2 - x1, + "*" => x1 * x2, + "/" => x2 / x1, + _ => 0, + }; + + v.push(x); + } + } + v[0] + } +} diff --git a/src/bin/excel-sheet-column-number.rs b/src/bin/excel-sheet-column-number.rs new file mode 100644 index 00000000..7101263e --- /dev/null +++ b/src/bin/excel-sheet-column-number.rs @@ -0,0 +1,20 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + println!("{}", Solution::title_to_number("AB".to_string())); + println!("{}", Solution::title_to_number("ZY".to_string())); +} + +struct Solution; + +impl Solution { + pub fn title_to_number(column_title: String) -> i32 { + let mut r = 0; + + for &i in column_title.as_bytes() { + r += r * 25 + (i - b'A') as i32 + 1; + } + + r + } +} diff --git a/src/bin/excel-sheet-column-title.rs b/src/bin/excel-sheet-column-title.rs new file mode 100644 index 00000000..74b7f4f3 --- /dev/null +++ b/src/bin/excel-sheet-column-title.rs @@ -0,0 +1,29 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + println!("{}", Solution::convert_to_title(701)); + println!("{}", Solution::convert_to_title(27)); + println!("{}", Solution::convert_to_title(28)); + println!("{}", Solution::convert_to_title(29)); + println!("{}", Solution::convert_to_title(26)); + println!("{}", Solution::convert_to_title(1)); + println!("{}", Solution::convert_to_title(26)); + println!("{}", Solution::convert_to_title(52)); +} + +struct Solution; + +impl Solution { + pub fn convert_to_title(column_number: i32) -> String { + let mut s = String::new(); + + let mut column_number = column_number; + while column_number > 0 { + let pop = (column_number - 1) % 26; + column_number = (column_number - 1) / 26; + s.push(('A' as u8 + pop as u8) as char); + } + + s.chars().rev().collect::() + } +} diff --git a/src/bin/extra-characters-in-a-string.rs b/src/bin/extra-characters-in-a-string.rs new file mode 100644 index 00000000..67c6c4a9 --- /dev/null +++ b/src/bin/extra-characters-in-a-string.rs @@ -0,0 +1,24 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn min_extra_char(s: String, dictionary: Vec) -> i32 { + let mut set: std::collections::HashSet<_> = dictionary.iter().map(|x| x.as_str()).collect(); + let mut dp = vec![vec![-1; s.len()]; s.len()]; + + let n = s.len(); + let mut dp = vec![0; n + 1]; + for i in 1..=n { + dp[i] = dp[i - 1] + 1; + for j in 1..=i { + if set.contains(&s[j - 1..i]) { + dp[i] = dp[i].min(dp[j - 1]); + } + } + } + dp[n] + } +} diff --git a/src/bin/factorial-trailing-zeroes.rs b/src/bin/factorial-trailing-zeroes.rs new file mode 100644 index 00000000..865d7607 --- /dev/null +++ b/src/bin/factorial-trailing-zeroes.rs @@ -0,0 +1,17 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn trailing_zeroes(n: i32) -> i32 { + let mut s = 0; + let mut n = n; + while n > 0 { + s += n / 5; + n /= 5; + } + s + } +} diff --git a/src/bin/fair-candy-swap.rs b/src/bin/fair-candy-swap.rs new file mode 100644 index 00000000..2f5ce28f --- /dev/null +++ b/src/bin/fair-candy-swap.rs @@ -0,0 +1,28 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn fair_candy_swap(a: Vec, b: Vec) -> Vec { + let mut s = std::collections::HashMap::::with_capacity(b.len()); + let (a_sum, mut b_sum) = (a.iter().sum::(), 0); + for i in b.into_iter() { + s.insert(i, ()); + b_sum += i; + } + + let mut result: Vec = Vec::with_capacity(2); + + for i in a.into_iter() { + if let Some(_) = s.get(&(i - (a_sum - b_sum) / 2)) { + result.push(i); + result.push(i - (a_sum - b_sum) / 2); + break; + } + } + + result + } +} diff --git a/src/bin/fan-zhuan-dan-ci-shun-xu-lcof.rs b/src/bin/fan-zhuan-dan-ci-shun-xu-lcof.rs new file mode 100644 index 00000000..53d366ce --- /dev/null +++ b/src/bin/fan-zhuan-dan-ci-shun-xu-lcof.rs @@ -0,0 +1,50 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn reverse_words(s: String) -> String { + if s.is_empty() { + return Default::default(); + } + + // 先去掉首位的空格 + let mut s = s.trim().as_bytes(); + + let mut i = s.len() - 1; + let mut new = vec![]; + + while !s.is_empty() { + match s.last() { + Some(&x) if x == b' ' => s = &s[..s.len() - 1], + _ => { + let mut i = s.len() - 1; + while let Some(&x) = s.get(i) { + if x != b' ' { + if i == 0 { + break; + } + i -= 1; + } else { + break; + } + } + + if i != 0 { + i += 1; + } + + new.extend_from_slice(&s[i..]); + new.push(b' '); + s = &s[..i]; + } + } + } + + new.pop(); + + String::from_utf8(new).unwrap() + } +} diff --git a/src/bin/fan-zhuan-lian-biao-lcof.rs b/src/bin/fan-zhuan-lian-biao-lcof.rs new file mode 100644 index 00000000..fec3eda8 --- /dev/null +++ b/src/bin/fan-zhuan-lian-biao-lcof.rs @@ -0,0 +1,58 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +// Definition for singly-linked list. +#[derive(PartialEq, Eq, Clone, Debug)] +pub struct ListNode { + pub val: i32, + pub next: Option>, +} + +impl ListNode { + #[inline] + fn new(val: i32) -> Self { + ListNode { next: None, val } + } +} +impl Solution { + pub fn reverse_list1(head: Option>) -> Option> { + let mut vals = vec![]; + let mut head = head; + + while head.is_some() { + let mut h = head.unwrap(); + vals.push(h.val); + head = h.next.take(); + } + + let mut r = None; + let mut current = &mut r; + + while let Some(val) = vals.pop() { + current.replace(Box::new(ListNode::new(val))); + current = &mut current.as_mut().unwrap().next; + } + + r + } + + pub fn reverse_list(mut head: Option>) -> Option> { + if head.is_none() { + return head; + } + + let mut next = head.as_mut().unwrap().next.take(); + + while let Some(n) = next.as_mut() { + let new_head = n.next.take(); + n.next = head; + head = next; + next = new_head; + } + + head + } +} diff --git a/src/bin/faulty-keyboard.rs b/src/bin/faulty-keyboard.rs new file mode 100644 index 00000000..9f7e62bc --- /dev/null +++ b/src/bin/faulty-keyboard.rs @@ -0,0 +1,33 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + /// 双端队列实现 + pub fn final_string(s: String) -> String { + use std::collections::LinkedList; + let mut list = LinkedList::new(); + let mut f = true; // true代表正向,false代表逆向 + + for i in s.chars() { + if i == 'i' { + f = !f; + continue; + } + + if f { + list.push_back(i); + } else { + list.push_front(i); + } + } + + if f { + list.into_iter().collect() + } else { + list.into_iter().rev().collect() + } + } +} diff --git a/src/bin/fei-bo-na-qi-shu-lie-lcof.rs b/src/bin/fei-bo-na-qi-shu-lie-lcof.rs new file mode 100644 index 00000000..cb987508 --- /dev/null +++ b/src/bin/fei-bo-na-qi-shu-lie-lcof.rs @@ -0,0 +1,21 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn fib(n: i32) -> i32 { + if n == 0 || n == 1 { + return n; + } + let (mut last, mut result) = (1, 1); + for _i in 2..n { + let result1 = result + last; + last = result; + result = result1 % 1000000007; + } + + result + } +} diff --git a/src/bin/filter-restaurants-by-vegan-friendly-price-and-distance.rs b/src/bin/filter-restaurants-by-vegan-friendly-price-and-distance.rs new file mode 100644 index 00000000..f066bd50 --- /dev/null +++ b/src/bin/filter-restaurants-by-vegan-friendly-price-and-distance.rs @@ -0,0 +1,34 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn filter_restaurants( + restaurants: Vec>, + vegan_friendly: i32, + max_price: i32, + max_distance: i32, + ) -> Vec { + use std::cmp::Ordering; + + let mut r = restaurants + .into_iter() + .filter(|x| vegan_friendly == 0 || x[2] == vegan_friendly) + .filter(|x| x[3] <= max_price) + .filter(|x| x[4] <= max_distance) + .map(|x| (x[0], x[1])) + .collect::>(); + + r.sort_by(|x, y| { + if x.1 == y.1 { + y.0.cmp(&x.0) + } else { + y.1.cmp(&x.1) + } + }); + + r.into_iter().map(|(x, _)| x).collect() + } +} diff --git a/src/bin/find-all-anagrams-in-a-string.rs b/src/bin/find-all-anagrams-in-a-string.rs new file mode 100644 index 00000000..96ed9f91 --- /dev/null +++ b/src/bin/find-all-anagrams-in-a-string.rs @@ -0,0 +1,41 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + /// 滑动窗口 + /// 记录滑动窗口里面的元素个数和p的元素个数是否相同,相同则表示满足条件 + pub fn find_anagrams(s: String, p: String) -> Vec { + if s.len() < p.len() { + return Vec::new(); + } + + let mut ans = vec![]; + let mut p_count = [0; 26]; + + for &i in p.as_bytes() { + p_count[(i - b'a') as usize] += 1; + } + + let mut s_count = [0; 26]; + + let bytes = s.as_bytes(); + + for i in 0..s.len() { + if i < p.len() { + s_count[(bytes[i] - b'a') as usize] += 1; + } else { + s_count[(bytes[i] - b'a') as usize] += 1; + s_count[(bytes[i - p.len()] - b'a') as usize] -= 1; + } + + if s_count == p_count { + ans.push((i - p.len() + 1) as i32); + } + } + + ans + } +} diff --git a/src/bin/find-all-duplicates-in-an-array.rs b/src/bin/find-all-duplicates-in-an-array.rs new file mode 100644 index 00000000..ec212497 --- /dev/null +++ b/src/bin/find-all-duplicates-in-an-array.rs @@ -0,0 +1,28 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + println!( + "{:?}", + Solution::find_duplicates(vec![4, 3, 2, 7, 8, 2, 3, 1]) + ) +} + +struct Solution; + +impl Solution { + pub fn find_duplicates(nums: Vec) -> Vec { + let mut nums = nums; + let a = nums.len() + 1; + + for i in 0..nums.len() { + let index = (nums[i] as usize % a) - 1usize; + nums[index] += a as i32; + } + + nums.into_iter() + .enumerate() + .filter(|&(i, x)| x / (a as i32) == 2) + .map(|(i, x)| i as i32 + 1) + .collect() + } +} diff --git a/src/bin/find-all-k-distant-indices-in-an-array.rs b/src/bin/find-all-k-distant-indices-in-an-array.rs new file mode 100644 index 00000000..6e596bb1 --- /dev/null +++ b/src/bin/find-all-k-distant-indices-in-an-array.rs @@ -0,0 +1,38 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + let s = Solution::find_k_distant_indices(vec![3, 4, 9, 1, 3, 9, 5], 9, 1); + println!("{s:?}"); + + let s = Solution::find_k_distant_indices(vec![2, 2, 2, 2, 2], 2, 2); + println!("{s:?}"); +} + +struct Solution; + +impl Solution { + pub fn find_k_distant_indices(nums: Vec, key: i32, k: i32) -> Vec { + let indeies: Vec = nums + .iter() + .enumerate() + .filter(|(_, &v)| v == key) + .map(|(i, _)| i) + .collect(); + + let mut data = vec![]; + + nums.into_iter().enumerate().for_each(|(index, _value)| { + for &i in indeies.iter() { + if (index > i && index - i <= k as usize) || (index <= i && i - index <= k as usize) + { + data.push(index as i32); + break; + } + } + }); + + data.sort(); + + data + } +} diff --git a/src/bin/find-all-numbers-disappeared-in-an-array.rs b/src/bin/find-all-numbers-disappeared-in-an-array.rs new file mode 100644 index 00000000..dfbdf7f4 --- /dev/null +++ b/src/bin/find-all-numbers-disappeared-in-an-array.rs @@ -0,0 +1,39 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn find_disappeared_numbers1(nums: Vec) -> Vec { + let mut s = std::collections::HashMap::new(); + + for &i in nums.iter() { + s.insert(i, ()); + } + + let mut v = vec![]; + for i in 1..=nums.len() as i32 { + if s.get(&i).is_none() { + v.push(i); + } + } + + v + } + + pub fn find_disappeared_numbers(nums: Vec) -> Vec { + let mut nums = nums; + let l = nums.len(); + for i in 0..l { + let v = nums[i] - 1; + nums[v as usize % l] += l as i32; + } + + nums.into_iter() + .enumerate() + .filter(|&(_, x)| x <= (l as i32)) + .map(|x| x.0 as i32 + 1) + .collect() + } +} diff --git a/src/bin/find-and-replace-in-string.rs b/src/bin/find-and-replace-in-string.rs new file mode 100644 index 00000000..fe93ea65 --- /dev/null +++ b/src/bin/find-and-replace-in-string.rs @@ -0,0 +1,40 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn find_replace_string( + s: String, + indices: Vec, + sources: Vec, + targets: Vec, + ) -> String { + let mut map1: std::collections::HashMap<_, _> = std::collections::HashMap::new(); + let mut map2: std::collections::HashMap<_, _> = std::collections::HashMap::new(); + + for i in 0..indices.len() { + map1.insert(indices[i] as usize, &sources[i]); + map2.insert(indices[i] as usize, i); + } + + let mut result = Vec::new(); + let mut i = 0; + + while i < s.len() { + if let Some(x) = map1.get(&i) { + if s[i..].starts_with(x.as_str()) { + result.extend_from_slice(targets[*map2.get(&i).unwrap()].as_bytes()); + i += x.len(); + continue; + } + } + + result.push(s.as_bytes()[i]); + i += 1; + } + + unsafe { String::from_utf8_unchecked(result) } + } +} diff --git a/src/bin/find-bottom-left-tree-value.rs b/src/bin/find-bottom-left-tree-value.rs new file mode 100644 index 00000000..30960594 --- /dev/null +++ b/src/bin/find-bottom-left-tree-value.rs @@ -0,0 +1,53 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +// Definition for a binary tree node. +#[derive(Debug, PartialEq, Eq)] +pub struct TreeNode { + pub val: i32, + pub left: Option>>, + pub right: Option>>, +} + +impl TreeNode { + #[inline] + pub fn new(val: i32) -> Self { + TreeNode { + val, + left: None, + right: None, + } + } +} + +use std::cell::RefCell; +use std::rc::Rc; + +impl Solution { + pub fn find_bottom_left_value(root: Option>>) -> i32 { + let mut stack = vec![root]; + let mut result = 0; + while !stack.is_empty() { + let mut new_stack = vec![]; + let mut flag = false; + for node in stack.into_iter() { + if let Some(x) = node { + if !flag { + result = x.borrow().val; + flag = true; + } + new_stack.push(x.borrow_mut().left.take()); + new_stack.push(x.borrow_mut().right.take()); + } + } + + stack = new_stack; + flag = false; + } + + result + } +} diff --git a/src/bin/find-champion-i.rs b/src/bin/find-champion-i.rs new file mode 100644 index 00000000..76840e35 --- /dev/null +++ b/src/bin/find-champion-i.rs @@ -0,0 +1,29 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn find_champion(grid: Vec>) -> i32 { + let mut hash_set = std::collections::HashSet::new(); + let mut champion = 0; + + for i in 0..grid.len() { + for j in 0..grid[0].len() { + if i == j { + continue; + } + + let m = if grid[i][j] == 1 { i } else { j }; + if !hash_set.contains(&m) { + champion = m as i32; + } + + hash_set.insert(if grid[i][j] == 1 { j } else { i }); + } + } + + champion + } +} diff --git a/src/bin/find-champion-ii.rs b/src/bin/find-champion-ii.rs new file mode 100644 index 00000000..219bb0cf --- /dev/null +++ b/src/bin/find-champion-ii.rs @@ -0,0 +1,29 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn find_champion(n: i32, edges: Vec>) -> i32 { + use std::collections::HashSet; + + let mut s: HashSet<_> = edges.iter().map(|x| x[1]).collect(); + if s.len() != n as usize - 1 { + return -1; + } + + let mut result = None; + for i in edges { + if !s.contains(&i[0]) { + if result.is_some() && Some(i[0]) != result { + return -1; + } else { + result = Some(i[0]); + } + } + } + + result.unwrap_or(0) + } +} diff --git a/src/bin/find-common-elements-between-two-arrays.rs b/src/bin/find-common-elements-between-two-arrays.rs new file mode 100644 index 00000000..92de3a0b --- /dev/null +++ b/src/bin/find-common-elements-between-two-arrays.rs @@ -0,0 +1,36 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn find_intersection_values(nums1: Vec, nums2: Vec) -> Vec { + let (mut s, mut m) = ( + nums1 + .iter() + .map(|x| *x) + .collect::>(), + nums2 + .iter() + .map(|x| *x) + .collect::>(), + ); + let mut r1 = 0; + let mut r2 = 0; + + for i in nums1 { + if m.contains(&i) { + r1 += 1; + } + } + + for i in nums2 { + if s.contains(&i) { + r2 += 1; + } + } + + vec![r1, r2] + } +} diff --git a/src/bin/find-elements-in-a-contaminated-binary-tree.rs b/src/bin/find-elements-in-a-contaminated-binary-tree.rs new file mode 100644 index 00000000..20bea53b --- /dev/null +++ b/src/bin/find-elements-in-a-contaminated-binary-tree.rs @@ -0,0 +1,70 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +use std::cell::RefCell; +use std::rc::Rc; + +// Definition for a binary tree node. +#[derive(Debug, PartialEq, Eq)] +pub struct TreeNode { + pub val: i32, + pub left: Option>>, + pub right: Option>>, +} + +impl TreeNode { + #[inline] + pub fn new(val: i32) -> Self { + TreeNode { + val, + left: None, + right: None, + } + } +} + +struct FindElements { + root: Option>>, + v: std::collections::HashMap, +} + +/** + * `&self` means the method takes an immutable reference. + * If you need a mutable reference, change it to `&mut self` instead. + */ +impl FindElements { + fn new(root: Option>>) -> Self { + let mut v = std::collections::HashMap::new(); + let mut root = root; + Self::scan(&mut root, &mut v, 0); + Self { root, v } + } + + fn scan( + root: &mut Option>>, + v: &mut std::collections::HashMap, + val: i32, + ) { + if root.is_some() { + v.insert(val, ()); + root.as_ref().unwrap().borrow_mut().val = val; + Self::scan( + &mut root.as_ref().unwrap().borrow_mut().left, + v, + val * 2 + 1, + ); + Self::scan( + &mut root.as_ref().unwrap().borrow_mut().right, + v, + val * 2 + 2, + ); + } + } + + fn find(&self, target: i32) -> bool { + self.v.get(&target).is_some() + } +} diff --git a/src/bin/find-first-and-last-position-of-element-in-sorted-array.rs b/src/bin/find-first-and-last-position-of-element-in-sorted-array.rs new file mode 100644 index 00000000..910f11f8 --- /dev/null +++ b/src/bin/find-first-and-last-position-of-element-in-sorted-array.rs @@ -0,0 +1,81 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + assert_eq!( + vec![3, 4], + Solution::search_range(vec![5, 7, 7, 8, 8, 10], 8) + ); +} + +struct Solution; + +impl Solution { + /// 方法1:遍历整个数组,找出相应的下标位置 + pub fn search_range1(nums: Vec, target: i32) -> Vec { + let mut v = vec![-1; 2]; + + for (index, value) in nums.into_iter().enumerate() { + if value != target { + continue; + } + + if v[0] == -1 { + v[0] = index as i32; + } + + v[1] = index as i32; + } + + v + } + + /// 二分查找法 + pub fn search_range(nums: Vec, target: i32) -> Vec { + let mut v = vec![-1; 2]; + if nums.is_empty() { + return v; + } + + let (mut start, mut end) = (0, nums.len() - 1); + + while start <= end { + let middle = (start + end) >> 1; + if nums[middle] == target && (middle == 0 || nums[middle - 1] < target) { + v[0] = middle as i32; + break; + } else if nums[middle] == target && middle != 0 && nums[middle - 1] == target { + end = middle - 1; + } else if nums[middle] > target { + if middle == 0 { + break; + } + end = middle - 1; + } else { + start = middle + 1; + } + } + + let (mut start, mut end) = (0, nums.len() - 1); + while start <= end { + let middle = (start + end) >> 1; + if nums[middle] == target && (middle == nums.len() - 1 || nums[middle + 1] > target) { + v[1] = middle as i32; + break; + } else if nums[middle] == target + && middle != nums.len() - 1 + && nums[middle + 1] == target + { + start = middle + 1; + } else if nums[middle] > target { + if middle == 0 { + break; + } + end = middle - 1; + } else { + start = middle + 1; + } + } + + v + } +} diff --git a/src/bin/find-indices-with-index-and-value-difference-i.rs b/src/bin/find-indices-with-index-and-value-difference-i.rs new file mode 100644 index 00000000..e47ec504 --- /dev/null +++ b/src/bin/find-indices-with-index-and-value-difference-i.rs @@ -0,0 +1,42 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn find_indices1(nums: Vec, index_difference: i32, value_difference: i32) -> Vec { + for i in 0..nums.len() { + for j in i + index_difference as usize..nums.len() { + if (nums[i] - nums[j]).abs() >= value_difference { + return vec![i as i32, j as i32]; + } + } + } + + vec![-1, -1] + } + + pub fn find_indices(nums: Vec, index_difference: i32, value_difference: i32) -> Vec { + let (mut max_id, mut min_id) = (0, 0); + + for j in index_difference as usize..nums.len() { + let i = j - index_difference as usize; + if nums[i] > nums[max_id] { + max_id = i; + } else if nums[i] < nums[min_id] { + min_id = i; + } + + if nums[j] - nums[min_id] >= value_difference { + return vec![min_id as i32, j as i32]; + } + + if nums[max_id] - nums[j] >= value_difference { + return vec![max_id as i32, j as i32]; + } + } + + vec![-1, -1] + } +} diff --git a/src/bin/find-k-closest-elements.rs b/src/bin/find-k-closest-elements.rs new file mode 100644 index 00000000..60dbd134 --- /dev/null +++ b/src/bin/find-k-closest-elements.rs @@ -0,0 +1,79 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + // assert_eq!(0, Solution::split(&vec![1, 2, 3, 7, 8, 9], 1)); + // assert_eq!(1, Solution::split(&vec![1, 2, 3, 7, 8, 9], 2)); + // assert_eq!(2, Solution::split(&vec![1, 2, 3, 7, 8, 9], 3)); + // assert_eq!(2, Solution::split(&vec![1, 2, 3, 7, 8, 9], 4)); + // assert_eq!(3, Solution::split(&vec![1, 2, 3, 7, 8, 9], 7)); + // assert_eq!(4, Solution::split(&vec![1, 2, 3, 7, 8, 9], 8)); + // assert_eq!(5, Solution::split(&vec![1, 2, 3, 7, 8, 9], 9)); + assert_eq!(1, Solution::split(&vec![1, 2, 2, 2, 2, 2, 3, 3, 3, 3], 2)); + assert_eq!(0, Solution::split(&vec![1, 2, 2, 2, 2, 2, 3, 3, 3, 3], -1)); +} + +struct Solution; + +impl Solution { + pub fn find_closest_elements(arr: Vec, k: i32, x: i32) -> Vec { + if x < arr[0] { + return arr[..k as usize].to_vec(); + } + + if x < arr[0] { + return arr[arr.len() - k as usize..].to_vec(); + } + + if arr.len() == 1 { + return arr; + } + + let index = Self::split(&arr, x); + let (mut start, mut end, k) = (index, index, k as usize); + while end - start < k - 1 { + if start == 0 { + end += 1; + } else if end == arr.len() - 1 { + start -= 1; + } else { + println!("{}, {}, aaa", x - arr[start - 1], arr[end + 1] - x); + if x - arr[start - 1] > arr[end + 1] - x { + end += 1; + } else { + start -= 1; + } + } + } + arr[start..=end].to_vec() + } + + // 二分查找找到最接近x的元素的下标 + pub fn split(arr: &Vec, x: i32) -> usize { + let (mut start, mut end) = (0, arr.len() - 1); + loop { + if end - start <= 1 { + if arr[end] - x >= x - arr[start] { + break start; + } else { + break end; + } + } + let mut index = (start + end) / 2; + if arr[index] > x { + end = index; + } else if arr[index] < x { + start = index; + } else { + while index > 0 { + if arr[index - 1] == x { + index -= 1; + } else { + break; + } + } + + break index; + } + } + } +} diff --git a/src/bin/find-largest-value-in-each-tree-row.rs b/src/bin/find-largest-value-in-each-tree-row.rs new file mode 100644 index 00000000..318fa505 --- /dev/null +++ b/src/bin/find-largest-value-in-each-tree-row.rs @@ -0,0 +1,61 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +// Definition for a binary tree node. +#[derive(Debug, PartialEq, Eq)] +pub struct TreeNode { + pub val: i32, + pub left: Option>>, + pub right: Option>>, +} + +impl TreeNode { + #[inline] + pub fn new(val: i32) -> Self { + TreeNode { + val, + left: None, + right: None, + } + } +} + +use std::cell::RefCell; +use std::rc::Rc; + +impl Solution { + pub fn largest_values(root: Option>>) -> Vec { + if root.is_none() { + return vec![]; + } + let mut stack = vec![root]; + let mut result = vec![]; + while !stack.is_empty() { + let mut new = vec![]; + let mut r: Option = None; + while let Some(node) = stack.pop() { + if node.is_none() { + continue; + } + let v = node.as_ref().unwrap().borrow().val; + r = r.map_or(Option::from(v), |x| Option::from(x.max(v))); + if let Some(x) = node.as_ref().unwrap().borrow_mut().left.take() { + new.push(Some(x)); + } + + if let Some(x) = node.as_ref().unwrap().borrow_mut().right.take() { + new.push(Some(x)); + } + } + if r.is_some() { + result.push(r.unwrap()); + } + stack = new; + } + + result + } +} diff --git a/src/bin/find-maximum-number-of-string-pairs.rs b/src/bin/find-maximum-number-of-string-pairs.rs new file mode 100644 index 00000000..b404289d --- /dev/null +++ b/src/bin/find-maximum-number-of-string-pairs.rs @@ -0,0 +1,32 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn maximum_number_of_string_pairs(words: Vec) -> i32 { + use std::iter::FromIterator; + let mut hash = std::collections::HashMap::new(); + let mut result = 0; + + for mut i in words { + let reverse = String::from_iter(i.chars().into_iter().rev()); + let count = hash.remove(&reverse).unwrap_or(0); + match count { + x if x > 1 => { + result += 1; + hash.insert(reverse, count - 1); + } + + 1 => result += 1, + 0 => { + hash.entry(i).and_modify(|x| *x += 1).or_insert(1); + } + _ => unreachable!(), + } + } + + result + } +} diff --git a/src/bin/find-minimum-in-rotated-sorted-array-ii.rs b/src/bin/find-minimum-in-rotated-sorted-array-ii.rs new file mode 100644 index 00000000..4d27152a --- /dev/null +++ b/src/bin/find-minimum-in-rotated-sorted-array-ii.rs @@ -0,0 +1,24 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn find_min(numbers: Vec) -> i32 { + let (mut start, mut end) = (0, numbers.len() - 1); + + while start < end { + let middile = start + (end - start) / 2; + if numbers[middile] < numbers[end] { + end = middile; + } else if numbers[middile] > numbers[end] { + start = middile + 1; + } else { + end -= 1; + } + } + + numbers[start] + } +} diff --git a/src/bin/find-minimum-in-rotated-sorted-array.rs b/src/bin/find-minimum-in-rotated-sorted-array.rs new file mode 100644 index 00000000..18fbcf5d --- /dev/null +++ b/src/bin/find-minimum-in-rotated-sorted-array.rs @@ -0,0 +1,30 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + assert_eq!(1, Solution::find_min(vec![3, 4, 5, 1, 2])); + assert_eq!(0, Solution::find_min(vec![4, 5, 6, 7, 0, 1, 2])); + assert_eq!(11, Solution::find_min(vec![11, 13, 15, 17])); +} + +struct Solution; + +impl Solution { + pub fn find_min(nums: Vec) -> i32 { + if nums[0] < *nums.last().unwrap() { + return nums[0]; + } + + let (mut start, mut end) = (0, nums.len() - 1); + + while start < end { + let middle = (start + end) / 2; + if nums[middle] > nums[end] { + start = middle + 1; + } else { + end = middle; + } + } + + nums[end] + } +} diff --git a/src/bin/find-missing-and-repeated-values.rs b/src/bin/find-missing-and-repeated-values.rs new file mode 100644 index 00000000..5dd13174 --- /dev/null +++ b/src/bin/find-missing-and-repeated-values.rs @@ -0,0 +1,28 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn find_missing_and_repeated_values(grid: Vec>) -> Vec { + let mut hash = std::collections::HashMap::new(); + + for i in 0..grid.len() { + for j in 0..grid[0].len() { + *hash.entry(grid[i][j]).or_insert(0) += 1; + } + } + + let mut result = vec![0, 0]; + for i in 1..=(grid.len() * grid.len()) as i32 { + match hash.get(&i) { + Some(&x) if x == 2 => result[0] = i, + None => result[1] = i, + _ => {} + } + } + + result + } +} diff --git a/src/bin/find-missing-observations.rs b/src/bin/find-missing-observations.rs new file mode 100644 index 00000000..b7122138 --- /dev/null +++ b/src/bin/find-missing-observations.rs @@ -0,0 +1,35 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn missing_rolls(rolls: Vec, mean: i32, n: i32) -> Vec { + let mut m = rolls.len() as i32; + let total = mean * (m + n); + let rolls_sum: i32 = rolls.into_iter().sum(); + let mut n_sum = total - rolls_sum; + let mut result = Vec::with_capacity(n as usize); + + if n_sum > n * 6 || n_sum < n { + return vec![]; + } + + for i in 1..=n { + match n_sum - (n - i) { + x if x >= 0 && x <= 5 => { + result.push(x); + n_sum -= x; + } + + _ => { + result.push(6); + n_sum -= 6; + } + } + } + + result + } +} diff --git a/src/bin/find-n-unique-integers-sum-up-to-zero.rs b/src/bin/find-n-unique-integers-sum-up-to-zero.rs new file mode 100644 index 00000000..297d33ec --- /dev/null +++ b/src/bin/find-n-unique-integers-sum-up-to-zero.rs @@ -0,0 +1,24 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn sum_zero(n: i32) -> Vec { + if n == 1 { + return vec![0]; + } + let mut v = Vec::with_capacity(n as usize); + for i in 1..=n / 2 { + v.push(i); + v.push(-i); + } + + if n % 2 == 1 { + v.push(0); + } + + v + } +} diff --git a/src/bin/find-original-array-from-doubled-array.rs b/src/bin/find-original-array-from-doubled-array.rs new file mode 100644 index 00000000..e37c48dd --- /dev/null +++ b/src/bin/find-original-array-from-doubled-array.rs @@ -0,0 +1,35 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn find_original_array(changed: Vec) -> Vec { + let mut changed = changed; + changed.sort(); + let mut map = std::collections::HashMap::new(); + let mut result = vec![]; + + for i in changed { + if let Some(x) = map.get_mut(&i) { + if *x > 0 { + *x -= 1; + } + + if *x == 0 { + map.remove(&i); + } + } else { + result.push(i); + map.entry(i * 2).and_modify(|x| *x += 1).or_insert(1); + } + } + + if map.is_empty() { + result + } else { + vec![] + } + } +} diff --git a/src/bin/find-peak-element.rs b/src/bin/find-peak-element.rs new file mode 100644 index 00000000..20e2693f --- /dev/null +++ b/src/bin/find-peak-element.rs @@ -0,0 +1,39 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn find_peak_element1(nums: Vec) -> i32 { + let mut start = 0; + for i in 1..nums.len() { + if nums[i] > nums[i - 1] { + start = i as i32; + } + + if i + 1 < nums.len() && nums[i] > nums[i + 1] { + break; + } + } + + start + } + + /// 二分查找,当中间元素大于前一个元素时, + pub fn find_peak_element(nums: Vec) -> i32 { + let (mut start, mut end) = (0, nums.len() - 1); + + while start < end { + let middle = (start + end) / 2; + + if nums[middle] > nums[middle + 1] { + end = middle; + } else { + start = middle + 1; + } + } + + start as i32 + } +} diff --git a/src/bin/find-pivot-index.rs b/src/bin/find-pivot-index.rs new file mode 100644 index 00000000..7c74927e --- /dev/null +++ b/src/bin/find-pivot-index.rs @@ -0,0 +1,22 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn pivot_index(nums: Vec) -> i32 { + let sum: i32 = nums.iter().sum(); + let mut s = 0; + + for i in 0..nums.len() { + if sum - nums[i] - s == s { + return i as i32; + } + + s += nums[i]; + } + + -1 + } +} diff --git a/src/bin/find-players-with-zero-or-one-losses.rs b/src/bin/find-players-with-zero-or-one-losses.rs new file mode 100644 index 00000000..248d46bb --- /dev/null +++ b/src/bin/find-players-with-zero-or-one-losses.rs @@ -0,0 +1,31 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn find_winners(matches: Vec>) -> Vec> { + let mut winners = std::collections::HashSet::new(); + let mut losers = std::collections::HashMap::new(); + + for i in matches { + losers.entry(i[1]).and_modify(|x| *x += 1).or_insert(1); + winners.remove(&i[1]); + if !losers.contains_key(&i[0]) { + winners.insert(i[0]); + } + } + + let mut w: Vec = winners.into_iter().collect(); + let mut l: Vec = losers + .into_iter() + .filter_map(|x| if x.1 == 1 { Some(x.0) } else { None }) + .collect(); + + w.sort_unstable(); + l.sort_unstable(); + + vec![w, l] + } +} diff --git a/src/bin/find-positive-integer-solution-for-a-given-equation.rs b/src/bin/find-positive-integer-solution-for-a-given-equation.rs new file mode 100644 index 00000000..7ae44a82 --- /dev/null +++ b/src/bin/find-positive-integer-solution-for-a-given-equation.rs @@ -0,0 +1,37 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +/* + * // This is the custom function interface. + * // You should not implement it, or speculate about its implementation + */ +struct CustomFunction; +impl CustomFunction { + pub fn f(x: i32, y: i32) -> i32 { + unimplemented!() + } +} +impl Solution { + pub fn find_solution(customfunction: &CustomFunction, z: i32) -> Vec> { + let mut result = vec![]; + let (mut x, mut y) = (1, 1000); + + while x < 1000 && y > 0 { + let r = CustomFunction::f(x, y); + if r > z { + y -= 1; + } else if r < z { + x += 1; + } else { + result.push(vec![x, y]); + x += 1; + y -= 1; + } + } + + result + } +} diff --git a/src/bin/find-resultant-array-after-removing-anagrams.rs b/src/bin/find-resultant-array-after-removing-anagrams.rs new file mode 100644 index 00000000..a24a889f --- /dev/null +++ b/src/bin/find-resultant-array-after-removing-anagrams.rs @@ -0,0 +1,41 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn remove_anagrams(words: Vec) -> Vec { + let mut result = vec![words[0].clone()]; + for i in 1..words.len() { + if !Self::f(words[i - 1].as_bytes(), words[i].as_bytes()) { + result.push(words[i].clone()); + } + } + + result + } + + fn f(a: &[u8], b: &[u8]) -> bool { + if a.len() != b.len() { + return false; + } + + let mut map = std::collections::HashMap::new(); + for &i in a { + map.entry(i).and_modify(|x| *x += 1).or_insert(1); + } + + for i in b { + if map.contains_key(i) { + if map[i] == 1 { + map.remove(i); + } else { + map.entry(*i).and_modify(|x| *x -= 1); + } + } + } + + map.is_empty() + } +} diff --git a/src/bin/find-target-indices-after-sorting-array.rs b/src/bin/find-target-indices-after-sorting-array.rs new file mode 100644 index 00000000..c7963102 --- /dev/null +++ b/src/bin/find-target-indices-after-sorting-array.rs @@ -0,0 +1,29 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn target_indices(mut nums: Vec, target: i32) -> Vec { + nums.sort(); + + let mut left = -1; + let mut right = 0; + + for i in (0..nums.len()) { + if nums[i] == target { + if left == -1 { + left = i as i32; + } + + right = i as i32; + } + } + if left != -1 { + (left..=right).collect() + } else { + Default::default() + } + } +} diff --git a/src/bin/find-the-array-concatenation-value.rs b/src/bin/find-the-array-concatenation-value.rs new file mode 100644 index 00000000..af746e86 --- /dev/null +++ b/src/bin/find-the-array-concatenation-value.rs @@ -0,0 +1,31 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn find_the_array_conc_val(nums: Vec) -> i64 { + let (mut start, mut end) = (0, nums.len() - 1); + let mut r = 0; + while start <= end { + if start == end { + r += nums[start] as i64; + break; + } else { + let x = nums[start] as i64; + let mut y = nums[end] as i64; + let mut m = 1; + while m <= y { + m *= 10; + } + r += (x * m) + y; + } + + start += 1; + end -= 1; + } + + r + } +} diff --git a/src/bin/find-the-difference.rs b/src/bin/find-the-difference.rs new file mode 100644 index 00000000..87e8617c --- /dev/null +++ b/src/bin/find-the-difference.rs @@ -0,0 +1,25 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn find_the_difference(s: String, t: String) -> char { + let mut h = vec![0u8; 26]; + + for i in s.bytes() { + h[(i - b'a') as usize] += 1; + } + + for i in t.bytes() { + if h[(i - b'a') as usize] == 0 { + return i as char; + } + + h[(i - b'a') as usize] -= 1; + } + + 'a' + } +} diff --git a/src/bin/find-the-distinct-difference-array.rs b/src/bin/find-the-distinct-difference-array.rs new file mode 100644 index 00000000..74bd06b2 --- /dev/null +++ b/src/bin/find-the-distinct-difference-array.rs @@ -0,0 +1,31 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn distinct_difference_array(nums: Vec) -> Vec { + let mut count = std::collections::HashMap::new(); + for &i in nums.iter() { + count.entry(i).and_modify(|x| *x += 1).or_insert(1); + } + + let mut result = Vec::with_capacity(nums.len()); + let mut set = std::collections::HashSet::new(); + + for i in nums { + set.insert(i); + let c = count[&i]; + if c == 1 { + count.remove(&i); + } else { + count.insert(i, c - 1); + } + + result.push((set.len() - count.len()) as i32); + } + + result + } +} diff --git a/src/bin/find-the-divisibility-array-of-a-string.rs b/src/bin/find-the-divisibility-array-of-a-string.rs new file mode 100644 index 00000000..1ce6f945 --- /dev/null +++ b/src/bin/find-the-divisibility-array-of-a-string.rs @@ -0,0 +1,21 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn divisibility_array(word: String, m: i32) -> Vec { + let mut result = vec![0; word.len()]; + let m = m as i64; + let mut s = 0i64; + for (i, j) in word.bytes().enumerate() { + s = (s * 10 + (j - b'0') as i64) % m; + if s == 0 { + result[i] = 1; + } + } + + result + } +} diff --git a/src/bin/find-the-duplicate-number.rs b/src/bin/find-the-duplicate-number.rs new file mode 100644 index 00000000..7e9cf4c3 --- /dev/null +++ b/src/bin/find-the-duplicate-number.rs @@ -0,0 +1,31 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() { + assert_eq!(Solution::find_duplicate(vec![1, 3, 4, 2, 2]), 2); + assert_eq!(Solution::find_duplicate(vec![2, 2, 2]), 2); +} + +struct Solution; + +impl Solution { + /// 环形列表, 找到第一个入环的值 + pub fn find_duplicate(nums: Vec) -> i32 { + let (mut slow, mut fast) = (0, 0); + + while fast < nums.len() { + slow = nums[slow] as usize; + fast = nums[nums[fast] as usize] as usize; + if nums[slow] == nums[fast] { + break; + } + } + + let mut slow = 0; + while nums[slow] != nums[fast] { + slow = nums[slow] as usize; + fast = nums[fast] as usize; + } + + nums[slow] + } +} diff --git a/src/bin/find-the-highest-altitude.rs b/src/bin/find-the-highest-altitude.rs new file mode 100644 index 00000000..960997e3 --- /dev/null +++ b/src/bin/find-the-highest-altitude.rs @@ -0,0 +1,19 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn largest_altitude(gain: Vec) -> i32 { + let mut current = 0; + let mut result = 0; + + for i in gain { + result = result.max(current + i); + current = current + i; + } + + result + } +} diff --git a/src/bin/find-the-integer-added-to-array-i.rs b/src/bin/find-the-integer-added-to-array-i.rs new file mode 100644 index 00000000..5f7a5296 --- /dev/null +++ b/src/bin/find-the-integer-added-to-array-i.rs @@ -0,0 +1,18 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn added_integer(nums1: Vec, nums2: Vec) -> i32 { + let (mut min1, mut min2) = (nums1[0], nums2[0]); + + for i in 1..nums1.len() { + min1 = min1.min(nums1[i]); + min2 = min2.min(nums2[i]); + } + + min2 - min1 + } +} diff --git a/src/bin/find-the-k-or-of-an-array.rs b/src/bin/find-the-k-or-of-an-array.rs new file mode 100644 index 00000000..2dec3674 --- /dev/null +++ b/src/bin/find-the-k-or-of-an-array.rs @@ -0,0 +1,25 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn find_k_or(nums: Vec, k: i32) -> i32 { + let mut result = 0; + + for mut i in 0..32 { + if nums + .iter() + .map(|x| *x) + .filter(|x| (x >> i) & 1 == 1) + .count() + >= k as usize + { + result += 2i32.pow(i as _); + } + } + + result + } +} diff --git a/src/bin/find-the-longest-balanced-substring-of-a-binary-string.rs b/src/bin/find-the-longest-balanced-substring-of-a-binary-string.rs new file mode 100644 index 00000000..fbd2d4bb --- /dev/null +++ b/src/bin/find-the-longest-balanced-substring-of-a-binary-string.rs @@ -0,0 +1,36 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn find_the_longest_balanced_substring(s: String) -> i32 { + let mut max = 0; + let mut zero_num = 0; + let mut one_num = 0; + for &i in s.as_bytes() { + match i { + b'0' => { + if one_num != 0 { + one_num = 0; + zero_num = 0; + } + zero_num += 1; + } + b'1' => { + if one_num < zero_num { + one_num += 1; + } else { + zero_num = 0; + } + + max = max.max(one_num.min(zero_num) * 2); + } + _ => unreachable!(), + } + } + + max + } +} diff --git a/src/bin/find-the-losers-of-the-circular-game.rs b/src/bin/find-the-losers-of-the-circular-game.rs new file mode 100644 index 00000000..34c0aaae --- /dev/null +++ b/src/bin/find-the-losers-of-the-circular-game.rs @@ -0,0 +1,28 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn circular_game_losers(n: i32, k: i32) -> Vec { + let mut set = std::collections::HashSet::new(); + let mut current = 1; + for i in 1.. { + set.insert(current); + current = if (i * k + current) <= n { + i * k + current + } else if (i * k + current) % n == 0 { + n + } else { + (i * k + current) % n + }; + + if set.contains(¤t) { + break; + } + } + + (1..=n).filter(|i| !set.contains(i)).collect() + } +} diff --git a/src/bin/find-the-maximum-achievable-number.rs b/src/bin/find-the-maximum-achievable-number.rs new file mode 100644 index 00000000..05442eda --- /dev/null +++ b/src/bin/find-the-maximum-achievable-number.rs @@ -0,0 +1,11 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn the_maximum_achievable_x(num: i32, t: i32) -> i32 { + num + t * 2 + } +} diff --git a/src/bin/find-the-maximum-divisibility-score.rs b/src/bin/find-the-maximum-divisibility-score.rs new file mode 100644 index 00000000..7f7e4211 --- /dev/null +++ b/src/bin/find-the-maximum-divisibility-score.rs @@ -0,0 +1,29 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn max_div_score(nums: Vec, divisors: Vec) -> i32 { + let mut r = i32::MAX; + let mut max = 0; + for i in divisors { + let mut n = 0; + for &j in nums.iter() { + if j % i == 0 { + n += 1; + } + } + + if n > max { + r = i as i32; + max = n; + } else if n == max { + r = r.min(i as i32); + } + } + + r + } +} diff --git a/src/bin/find-the-minimum-and-maximum-number-of-nodes-between-critical-points.rs b/src/bin/find-the-minimum-and-maximum-number-of-nodes-between-critical-points.rs new file mode 100644 index 00000000..4ad4dae4 --- /dev/null +++ b/src/bin/find-the-minimum-and-maximum-number-of-nodes-between-critical-points.rs @@ -0,0 +1,62 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +// Definition for singly-linked list. +#[derive(PartialEq, Eq, Clone, Debug)] +pub struct ListNode { + pub val: i32, + pub next: Option>, +} + +impl ListNode { + #[inline] + fn new(val: i32) -> Self { + ListNode { next: None, val } + } +} + +impl Solution { + pub fn nodes_between_critical_points(head: Option>) -> Vec { + let mut min_distance = i32::MAX; + let mut pre_value = head.as_ref().unwrap().val; + let mut pre_index = 0; // 前一个节点的下标 + let mut first_index = None; // 第一个极值的下标 + let mut pre_index_1 = None; // 前一个极值的下标 + + let mut current = head.unwrap().next; + while current.is_some() { + let mut c = current.unwrap(); + let current_val = c.val; + let next = c.next.take(); + if next.is_some() { + let next_value = next.as_ref().unwrap().val; + if (current_val < pre_value && current_val < next_value) + || (current_val > pre_value && current_val > next_value) + { + if first_index.is_none() { + first_index = Some(pre_index + 1); + } + + if let Some(x) = pre_index_1 { + min_distance = min_distance.min(pre_index + 1 - x); + } + + pre_index_1 = Some(pre_index + 1); + } + } + + pre_index += 1; + current = next; + pre_value = current_val; + } + + if first_index != pre_index_1 { + vec![min_distance, pre_index_1.unwrap() - first_index.unwrap()] + } else { + vec![-1, -1] + } + } +} diff --git a/src/bin/find-the-minimum-possible-sum-of-a-beautiful-array.rs b/src/bin/find-the-minimum-possible-sum-of-a-beautiful-array.rs new file mode 100644 index 00000000..d6ef9ba0 --- /dev/null +++ b/src/bin/find-the-minimum-possible-sum-of-a-beautiful-array.rs @@ -0,0 +1,14 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn minimum_possible_sum(n: i32, target: i32) -> i32 { + let n = n as i64; + let k = target as i64; + let m = n.min(k / 2); + ((m * (m + 1) + (n - m - 1 + k * 2) * (n - m)) / 2 % 1_000_000_007) as i32 + } +} diff --git a/src/bin/find-the-original-array-of-prefix-xor.rs b/src/bin/find-the-original-array-of-prefix-xor.rs new file mode 100644 index 00000000..7102561c --- /dev/null +++ b/src/bin/find-the-original-array-of-prefix-xor.rs @@ -0,0 +1,21 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() { + println!("{:?}", Solution::find_array(vec![5, 2, 0, 3, 1])); +} + +struct Solution; + +impl Solution { + pub fn find_array(pref: Vec) -> Vec { + let mut arr = vec![0; pref.len()]; + arr[0] = pref[0]; + let mut x = arr[0]; + for i in 1..pref.len() { + arr[i] = x ^ pref[i]; + x ^= arr[i]; + } + + arr + } +} diff --git a/src/bin/find-the-peaks.rs b/src/bin/find-the-peaks.rs new file mode 100644 index 00000000..b6c79c56 --- /dev/null +++ b/src/bin/find-the-peaks.rs @@ -0,0 +1,18 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn find_peaks(mountain: Vec) -> Vec { + let mut result = vec![]; + for i in 1..mountain.len() - 1 { + if mountain[i] > mountain[i - 1] && mountain[i] > mountain[i + 1] { + result.push(i as i32); + } + } + + result + } +} diff --git a/src/bin/find-the-pivot-integer.rs b/src/bin/find-the-pivot-integer.rs new file mode 100644 index 00000000..519b4f36 --- /dev/null +++ b/src/bin/find-the-pivot-integer.rs @@ -0,0 +1,29 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + /// 设值为x + /// (1 + x) * (x - 1 + 1) / 2= (x + n) * (n - x + 1) / 2 + /// (1 + x) * x = (n + x) * (n - x + 1) + /// x**2 + x = n ** 2 - nx + n + nx - x**2 + x + /// 2 * x ** 2 = n ** 2 + n + pub fn pivot_integer(n: i32) -> i32 { + let x = n * n + n; + if x % 2 == 1 { + return -1; + } + + for i in 1..=n { + if i * i == x / 2 { + return i; + } else if i * i > x / 2 { + return -1; + } + } + + -1 + } +} diff --git a/src/bin/find-the-punishment-number-of-an-integer.rs b/src/bin/find-the-punishment-number-of-an-integer.rs new file mode 100644 index 00000000..3e84f891 --- /dev/null +++ b/src/bin/find-the-punishment-number-of-an-integer.rs @@ -0,0 +1,35 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn punishment_number(n: i32) -> i32 { + (1..=n).into_iter().filter(Self::is).map(|x| x * x).sum() + } + + pub fn is(n: &i32) -> bool { + fn s(mut num: i32, except: i32) -> bool { + if num == except { + return true; + } + + if num == 0 { + return false; + } + let mut flag = 10; + while num % flag != num { + if s(num / flag, except - (num % flag)) { + return true; + } + + flag *= 10; + } + + false + } + + s(n * n, *n) + } +} diff --git a/src/bin/find-the-score-of-all-prefixes-of-an-array.rs b/src/bin/find-the-score-of-all-prefixes-of-an-array.rs new file mode 100644 index 00000000..56b5a4fc --- /dev/null +++ b/src/bin/find-the-score-of-all-prefixes-of-an-array.rs @@ -0,0 +1,21 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn find_prefix_score(mut nums: Vec) -> Vec { + let mut max = 0i64; + let mut sum = 0; + let mut result = vec![0; nums.len()]; + for i in 0..nums.len() { + max = max.max(nums[i] as i64); + let s = max + nums[i] as i64; + result[i] = sum + s; + sum += s; + } + + result + } +} diff --git a/src/bin/find-the-town-judge.rs b/src/bin/find-the-town-judge.rs new file mode 100644 index 00000000..08439f1b --- /dev/null +++ b/src/bin/find-the-town-judge.rs @@ -0,0 +1,33 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +use std::future::ready; + +fn main() {} + +struct Solution; + +impl Solution { + pub fn find_judge(n: i32, trust: Vec>) -> i32 { + let mut map = std::collections::HashMap::new(); + let mut m = std::collections::HashSet::new(); + + for v in trust { + map.entry(v[1]).and_modify(|x| *x += 1).or_insert(1); + m.insert(v[0]); + } + + let mut result = None; + for i in 1..=n { + let v = map.get(&i).unwrap_or(&0); + if *v == n - 1 && !m.contains(&i) { + if result.is_none() { + result = Some(i); + } else { + return -1; + } + } + } + + result.unwrap_or(-1) + } +} diff --git a/src/bin/find-the-width-of-columns-of-a-grid.rs b/src/bin/find-the-width-of-columns-of-a-grid.rs new file mode 100644 index 00000000..4cee0d87 --- /dev/null +++ b/src/bin/find-the-width-of-columns-of-a-grid.rs @@ -0,0 +1,21 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn find_column_width(grid: Vec>) -> Vec { + let mut result = vec![]; + + for i in 0..grid[0].len() { + let mut r = -1; + for j in 0..grid.len() { + r = r.max(grid[j][i].to_string().len() as i32); + } + result.push(r); + } + + result + } +} diff --git a/src/bin/find-winner-on-a-tic-tac-toe-game.rs b/src/bin/find-winner-on-a-tic-tac-toe-game.rs new file mode 100644 index 00000000..0ea26935 --- /dev/null +++ b/src/bin/find-winner-on-a-tic-tac-toe-game.rs @@ -0,0 +1,91 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn tictactoe(moves: Vec>) -> String { + let mut s = [['C'; 3]; 3]; + let mut flag = 'A'; + for i in moves.iter() { + s[i[0] as usize][i[1] as usize] = flag; + + if i[0] == 0 { + if i[1] == 0 { + if (s[0][1] == flag && s[0][2] == flag) + || (s[1][0] == flag && s[2][0] == flag) + || (s[1][1] == flag && s[2][2] == flag) + { + return flag.to_string(); + } + } else if i[1] == 1 { + if (s[0][0] == flag && s[0][2] == flag) || (s[1][1] == flag && s[2][1] == flag) + { + return flag.to_string(); + } + } else { + if (s[0][1] == flag && s[0][0] == flag) + || (s[1][2] == flag && s[2][2] == flag) + || (s[1][1] == flag && s[2][0] == flag) + { + return flag.to_string(); + } + } + } else if i[0] == 1 { + if i[1] == 0 { + if (s[1][1] == flag && s[1][2] == flag) || (s[0][0] == flag && s[2][0] == flag) + { + return flag.to_string(); + } + } else if i[1] == 1 { + if (s[1][0] == flag && s[1][2] == flag) + || (s[0][1] == flag && s[2][1] == flag) + || (s[0][0] == flag && s[2][2] == flag) + || (s[0][2] == flag && s[2][0] == flag) + { + return flag.to_string(); + } + } else { + if (s[0][2] == flag && s[2][2] == flag) || (s[1][0] == flag && s[1][1] == flag) + { + return flag.to_string(); + } + } + } else { + if i[1] == 0 { + if (s[2][1] == flag && s[2][2] == flag) + || (s[0][0] == flag && s[1][0] == flag) + || s[1][1] == flag && s[0][2] == flag + { + return flag.to_string(); + } + } else if i[1] == 1 { + if (s[2][0] == flag && s[2][2] == flag) || (s[1][1] == flag && s[0][1] == flag) + { + return flag.to_string(); + } + } else { + if (s[2][0] == flag && s[2][1] == flag) + || (s[1][2] == flag && s[0][2] == flag) + || (s[0][0] == flag && s[1][1] == flag) + { + return flag.to_string(); + } + } + } + + if flag == 'A' { + flag = 'B'; + } else { + flag = 'A'; + } + } + + if moves.len() < 9 { + "Pending".into() + } else { + "Draw".into() + } + } +} diff --git a/src/bin/find-xor-beauty-of-array.rs b/src/bin/find-xor-beauty-of-array.rs new file mode 100644 index 00000000..b4dcfae8 --- /dev/null +++ b/src/bin/find-xor-beauty-of-array.rs @@ -0,0 +1,11 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn xor_beauty(nums: Vec) -> i32 { + nums.into_iter().fold(0, |x, y| x ^ y) + } +} diff --git a/src/bin/finding-3-digit-even-numbers.rs b/src/bin/finding-3-digit-even-numbers.rs new file mode 100644 index 00000000..6fec6c62 --- /dev/null +++ b/src/bin/finding-3-digit-even-numbers.rs @@ -0,0 +1,62 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + /// 枚举100-999的数据 + pub fn find_even_numbers(digits: Vec) -> Vec { + let mut hash = std::collections::HashMap::new(); + + for i in digits { + hash.entry(i).and_modify(|x| *x += 1).or_insert(1); + } + let mut result = vec![]; + for j in 100..=999 { + if j % 2 == 1 { + continue; + } + + let x = j / 100; + let y = j / 10 % 10; + let z = j % 10; + + if x != y && y != z && x != z { + if hash.contains_key(&x) && hash.contains_key(&y) && hash.contains_key(&z) { + result.push(j); + } + } else if x == y && y != z { + match (hash.get(&x), hash.get(&z)) { + (Some(m), Some(_)) if *m >= 2 => { + result.push(j); + } + _ => {} + } + } else if x == z && z != y { + match (hash.get(&x), hash.get(&y)) { + (Some(m), Some(_)) if *m >= 2 => { + result.push(j); + } + _ => {} + } + } else if y == z && z != x { + match (hash.get(&z), hash.get(&x)) { + (Some(m), Some(_)) if *m >= 2 => { + result.push(j); + } + _ => {} + } + } else { + match hash.get(&x) { + Some(m) if *m >= 3 => { + result.push(j); + } + _ => {} + } + } + } + + result + } +} diff --git a/src/bin/finding-pairs-with-a-certain-sum.rs b/src/bin/finding-pairs-with-a-certain-sum.rs new file mode 100644 index 00000000..d2c29b20 --- /dev/null +++ b/src/bin/finding-pairs-with-a-certain-sum.rs @@ -0,0 +1,58 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + + +/** + * `&self` means the method takes an immutable reference. + * If you need a mutable reference, change it to `&mut self` instead. + */ + +struct FindSumPairs { + nums2_map: std::collections::HashMap, + nums1: Vec, + nums2: Vec, +} + +impl FindSumPairs { + + fn new(nums1: Vec, nums2: Vec) -> Self { + let mut nums2_map = std::collections::HashMap::new(); + + for &i in nums2.iter() { + nums2_map.entry(i).and_modify(|x| *x += 1).or_insert(1); + } + + + Self { + nums2_map, + nums1, + nums2, + } + } + + fn add(&mut self, index: i32, val: i32) { + let mut origin = self.nums2[index as usize]; + self.nums2[index as usize] += val; + self.nums2_map.entry(origin).and_modify(|x| *x-=1); + self.nums2_map.entry(origin + val).and_modify(|x| *x += 1).or_insert(1); + } + + fn count(&self, tot: i32) -> i32 { + let mut result = 0; + for &i in self.nums1.iter() { + result += *self.nums2_map.get(&(tot-i)).unwrap_or(&0); + } + + result + } +} + +/** + * Your FindSumPairs object will be instantiated and called as such: + * let obj = FindSumPairs::new(nums1, nums2); + * obj.add(index, val); + * let ret_2: i32 = obj.count(tot); + */ diff --git a/src/bin/first-bad-version.rs b/src/bin/first-bad-version.rs new file mode 100644 index 00000000..c91dbbfa --- /dev/null +++ b/src/bin/first-bad-version.rs @@ -0,0 +1,39 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() { + // println!("{}", Solution::new(1702766719).first_bad_version(2126753390)); + // println!("{}", Solution::new(1).first_bad_version(1)); + println!("{}", Solution::new(2).first_bad_version(2)); +} + +struct Solution { + n: i32, +} + +// The API isBadVersion is defined for you. +// isBadVersion(versions:i32)-> bool; +// to call it use self.isBadVersion(versions) + +impl Solution { + fn new(n: i32) -> Self { + Self { n } + } + + pub fn first_bad_version(&self, n: i32) -> i32 { + let mut good: i64 = 0; + let mut bad: i64 = n as i64; + while bad - good > 1 { + let mid = (good + bad + 1) / 2; + if self.isBadVersion(mid as i32) { + bad = mid; + } else { + good = mid; + } + } + bad as i32 + } + + fn isBadVersion(&self, versions: i32) -> bool { + self.n <= versions + } +} diff --git a/src/bin/first-completely-painted-row-or-column.rs b/src/bin/first-completely-painted-row-or-column.rs new file mode 100644 index 00000000..cf329fad --- /dev/null +++ b/src/bin/first-completely-painted-row-or-column.rs @@ -0,0 +1,35 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn first_complete_index(arr: Vec, mat: Vec>) -> i32 { + let mut r = arr.len(); + + let mut hash: std::collections::HashMap = Default::default(); + // s1存放每行的个数 + // s2存放没列的个数 + let (mut s1, mut s2) = (vec![0usize; mat.len()], vec![0usize; mat[0].len()]); + + for i in 0..mat.len() { + for j in 0..mat[0].len() { + hash.insert(mat[i][j], (i, j)); + } + } + + for i in 0..arr.len() { + let (x, y) = hash[&arr[i]]; + + s1[x] += 1usize; + s2[y] += 1usize; + + if s1[x] == mat[0].len() || s2[y] == mat.len() { + return i as i32; + } + } + + unreachable!() + } +} diff --git a/src/bin/first-missing-positive.rs b/src/bin/first-missing-positive.rs new file mode 100644 index 00000000..1b89468a --- /dev/null +++ b/src/bin/first-missing-positive.rs @@ -0,0 +1,68 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + /// 常规解法,是用hash表 + /// 是用O(n)的空间 + pub fn first_missing_positive1(nums: Vec) -> i32 { + let mut hash = std::collections::HashMap::new(); + + for i in nums.into_iter() { + if i > 0 { + hash.insert(i, ()); + } + } + + let mut min = 1; + + loop { + if hash.get(&min).is_some() { + min += 1; + } else { + break; + } + } + + min + } + + /// 当数组中不存在1时,最小的数肯定是1 + /// 当数组中存在非正数或者存在大于n+1的数(n为数组的长度),则数组中肯定在1~n+1之间有缺失,答案就在1~n+1之间 + /// 如果1~n+1没有数字缺失,答案就是n+1 + pub fn first_missing_positive(nums: Vec) -> i32 { + // 首先判断1是否在数组中,如果1不在数组中,则返回1 + if !nums.contains(&1) { + return 1; + } + + let mut nums = nums; + let length = nums.len() as i32 + 1; + + // 将所有<1和大于n+1的数改为1 + for i in nums.iter_mut() { + if *i < 1 || *i >= length { + *i = 1 + } + } + + // 遍历数组,将i对应的下标元素改为负数 + for i in 0..nums.len() { + let m = nums[i].abs(); + nums[m as usize - 1] = nums[m as usize - 1].abs() * -1; + } + + let mut result = nums.len() as i32 + 1; + + for (i, v) in nums.into_iter().enumerate() { + if v > 0 { + result = i as i32 + 1; + break; + } + } + + result + } +} diff --git a/src/bin/first-unique-character-in-a-string.rs b/src/bin/first-unique-character-in-a-string.rs index 04b5f176..369e4eda 100644 --- a/src/bin/first-unique-character-in-a-string.rs +++ b/src/bin/first-unique-character-in-a-string.rs @@ -1,3 +1,5 @@ +#![allow(dead_code, unused, unused_variables)] + fn main() {} struct Solution; diff --git a/src/bin/fizz-buzz.rs b/src/bin/fizz-buzz.rs new file mode 100644 index 00000000..84094054 --- /dev/null +++ b/src/bin/fizz-buzz.rs @@ -0,0 +1,25 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn fizz_buzz(n: i32) -> Vec { + let mut v = Vec::with_capacity(n as usize); + + for i in 1..=n { + if i % 3 == 0 && i % 5 == 0 { + v.push("FizzBuzz".to_string()); + } else if i % 3 == 0 { + v.push("Fizz".to_string()); + } else if i % 5 == 0 { + v.push("Buzz".to_string()); + } else { + v.push(i.to_string()); + } + } + + v + } +} diff --git a/src/bin/flipping-an-image.rs b/src/bin/flipping-an-image.rs new file mode 100644 index 00000000..0376031b --- /dev/null +++ b/src/bin/flipping-an-image.rs @@ -0,0 +1,29 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn flip_and_invert_image(image: Vec>) -> Vec> { + let mut image = image; + for i in 0..image.len() { + let (mut s, mut m) = (0, image[0].len() - 1); + + while s <= m { + if s == m { + image[i][s] ^= 1; + break; + } + + image[i].swap(s, m); + image[i][s] ^= 1; + image[i][m] ^= 1; + s += 1; + m -= 1; + } + } + + image + } +} diff --git a/src/bin/form-smallest-number-from-two-digit-arrays.rs b/src/bin/form-smallest-number-from-two-digit-arrays.rs new file mode 100644 index 00000000..ddfd5641 --- /dev/null +++ b/src/bin/form-smallest-number-from-two-digit-arrays.rs @@ -0,0 +1,44 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn min_number(nums1: Vec, nums2: Vec) -> i32 { + let mut r = i32::MAX; + + for i in 0..nums1.len() { + for j in 0..nums2.len() { + if nums1[i] == nums2[j] { + r = r.min(nums1[i]); + } else if nums1[i] < nums2[j] { + r = r.min(nums1[i] * 10 + nums2[j]); + } else { + r = r.min(nums1[i] + nums2[j] * 10); + } + } + } + + r + } + + pub fn min_number1(nums1: Vec, nums2: Vec) -> i32 { + let (mut x, mut y) = (0i32, 0i32); + + for i in nums1 { + x |= 1 << i; + } + + for i in nums2 { + y |= 1 << i; + } + + if x & y != 0 { + (x & y).trailing_zeros() as i32 + } else { + (x.trailing_zeros() * 10 + y.trailing_zeros()) + .min(y.trailing_zeros() * 10 + x.trailing_zeros()) as i32 + } + } +} diff --git a/src/bin/fraction-to-recurring-decimal.rs b/src/bin/fraction-to-recurring-decimal.rs new file mode 100644 index 00000000..98c18da2 --- /dev/null +++ b/src/bin/fraction-to-recurring-decimal.rs @@ -0,0 +1,76 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + println!("{}", Solution::fraction_to_decimal(1, 2)); + println!("{}", Solution::fraction_to_decimal(2, 1)); + println!("{}", Solution::fraction_to_decimal(4, 333)); + println!("{}", Solution::fraction_to_decimal(1, 5)); + println!("{}", Solution::fraction_to_decimal(424231, 5)); + println!("{}", Solution::fraction_to_decimal(1000000, 3)); + println!("{}", Solution::fraction_to_decimal(1, 3)); + println!("{}", Solution::fraction_to_decimal(1, 6)); + println!("{}", Solution::fraction_to_decimal(1, 333)); + println!("{}", Solution::fraction_to_decimal(1, 17)); + println!("{}", Solution::fraction_to_decimal(-50, 8)); + println!("{}", Solution::fraction_to_decimal(-50, -8)); + println!("{}", Solution::fraction_to_decimal(50, -8)); + println!("{}", Solution::fraction_to_decimal(-1, -2147483648)); +} + +struct Solution; + +impl Solution { + pub fn fraction_to_decimal(numerator: i32, denominator: i32) -> String { + // 用于保存出现过的余数 + let mut m = std::collections::HashMap::::new(); + let (mut numerator, mut denominator) = (numerator as i64, denominator as i64); + let mut flag = false; // false为当前为整数部分,true为小数部分 + let mut n = 0; + let (mut r1, mut r2) = (String::new(), String::new()); // r1整数,r2小数 + + if numerator < 0 && denominator > 0 { + r1.push('-'); + numerator *= -1; + } else if numerator > 0 && denominator < 0 { + r1.push('-'); + denominator *= -1; + } else if numerator < 0 && denominator < 0 { + denominator *= -1; + numerator *= -1; + } + + loop { + if !flag { + r1.push_str(&(numerator / denominator).to_string()); + numerator %= denominator; + if numerator < denominator { + flag = true; + numerator *= 10; + } + } else { + n += 1; + if let Some(&s) = m.get(&numerator) { + r2 = format!("{}({})", &r2[..s - 1], &r2[s - 1..]); + break; + } + m.insert(numerator, n); + if numerator > denominator { + r2.push_str(&(numerator / denominator).to_string()); + numerator %= denominator; + } else { + r2.push('0'); + } + numerator *= 10; + } + + if numerator == 0 { + break; + } + } + if r2 != "" { + format!("{}.{}", r1, r2) + } else { + r1 + } + } +} diff --git a/src/bin/frequency-tracker.rs b/src/bin/frequency-tracker.rs new file mode 100644 index 00000000..edc1312e --- /dev/null +++ b/src/bin/frequency-tracker.rs @@ -0,0 +1,68 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +/** + * `&self` means the method takes an immutable reference. + * If you need a mutable reference, change it to `&mut self` instead. + */ +/** + * Your FrequencyTracker object will be instantiated and called as such: + * let obj = FrequencyTracker::new(); + * obj.add(number); + * obj.delete_one(number); + * let ret_3: bool = obj.has_frequency(frequency); + */ + +struct FrequencyTracker { + /// 每个数字对应的次数 + s1: std::collections::HashMap, + /// 每个次数对应的数字个数 + s2: std::collections::HashMap, +} + +impl FrequencyTracker { + fn new() -> Self { + Self { + s1: Default::default(), + s2: Default::default(), + } + } + + fn add(&mut self, number: i32) { + self.s1.entry(number).and_modify(|x| *x += 1).or_insert(1); + let n = self.s1[&number]; + + self.s2.entry(n).and_modify(|x| *x += 1).or_insert(1); + self.remove_s2_or_delete(n - 1); + } + + fn remove_s2_or_delete(&mut self, times: i32) { + self.s2.entry(times).and_modify(|x| *x -= 1); + let &x = self.s2.get(×).unwrap_or(&0); + if x == 0 { + self.s2.remove(×); + } + } + + fn delete_one(&mut self, number: i32) { + self.s1.entry(number).and_modify(|x| *x -= 1); + match self.s1.get(&number) { + Some(&x) => { + if x == 0 { + self.s1.remove(&number); + } + + self.s2.entry(x).and_modify(|x| *x += 1).or_insert(1); + self.remove_s2_or_delete(x + 1); + } + _ => {} + } + } + + fn has_frequency(&self, frequency: i32) -> bool { + self.s2.get(&frequency).is_some() + } +} diff --git a/src/bin/g5c51o.rs b/src/bin/g5c51o.rs new file mode 100644 index 00000000..7d2b2503 --- /dev/null +++ b/src/bin/g5c51o.rs @@ -0,0 +1,24 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn top_k_frequent(nums: Vec, k: i32) -> Vec { + use std::cmp::Reverse; + + let mut hash = std::collections::HashMap::new(); + for i in nums { + hash.entry(i).and_modify(|x| *x += 1).or_insert(1); + } + + hash.into_iter() + .map(|(x, y)| (Reverse(y), x)) + .collect::>() + .into_iter() + .take(k as usize) + .map(|x| x.1) + .collect() + } +} diff --git a/src/bin/generate-a-string-with-characters-that-have-odd-counts.rs b/src/bin/generate-a-string-with-characters-that-have-odd-counts.rs new file mode 100644 index 00000000..c1f2cb08 --- /dev/null +++ b/src/bin/generate-a-string-with-characters-that-have-odd-counts.rs @@ -0,0 +1,19 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn generate_the_string(n: i32) -> String { + if n % 2 == 1 { + "a".repeat(n as usize) + } else { + let mut result = String::with_capacity(n as usize); + result.push('a'); + result.extend((0..n - 1).map(|_x| 'b')); + + result + } + } +} diff --git a/src/bin/generate-parentheses.rs b/src/bin/generate-parentheses.rs new file mode 100644 index 00000000..4a3e9aec --- /dev/null +++ b/src/bin/generate-parentheses.rs @@ -0,0 +1,25 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn generate_parenthesis(n: i32) -> Vec { + if n == 1 { + return vec!["()".into()]; + } + let mut v = std::collections::HashSet::new(); + for i in Self::generate_parenthesis(n - 1) { + for j in 0..i.len() { + let mut s = String::new(); + s.push_str(&i[..j]); + s.push_str("()"); + s.push_str(&i[j..]); + v.insert(s); + } + } + + v.into_iter().collect() + } +} diff --git a/src/bin/goal-parser-interpretation.rs b/src/bin/goal-parser-interpretation.rs index 007ad397..bbd0fdc6 100644 --- a/src/bin/goal-parser-interpretation.rs +++ b/src/bin/goal-parser-interpretation.rs @@ -1,6 +1,6 @@ -fn main() { +#![allow(dead_code, unused, unused_variables)] -} +fn main() {} struct Solution; diff --git a/src/bin/gou-jian-cheng-ji-shu-zu-lcof.rs b/src/bin/gou-jian-cheng-ji-shu-zu-lcof.rs new file mode 100644 index 00000000..07a35894 --- /dev/null +++ b/src/bin/gou-jian-cheng-ji-shu-zu-lcof.rs @@ -0,0 +1,57 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +use std::vec; + +fn main() {} + +struct Solution; + +impl Solution { + pub fn construct_arr1(a: Vec) -> Vec { + if a.is_empty() { + return vec![]; + } + + let mut v1 = vec![0; a.len()]; + let mut v2 = vec![0; a.len()]; + + for i in 0..a.len() { + if i == 0 { + v1[i] = a[i]; + v2[a.len() - 1] = a[a.len() - 1]; + } else { + v1[i] = a[i] * v1[i - 1]; + v2[a.len() - 1 - i] = a[a.len() - 1 - i] * v2[a.len() - i]; + } + } + + let mut r = Vec::with_capacity(a.len()); + + for i in 0..a.len() { + if i == 0 { + r.push(v2[i + 1]); + } else if i == a.len() - 1 { + r.push(v1[a.len() - 2]); + } else { + r.push(v1[i - 1] * v2[1 + i]); + } + } + + r + } + + pub fn construct_arr(a: Vec) -> Vec { + let mut r = vec![1; a.len()]; + + for i in 1..a.len() { + r[i] = a[i - 1] * r[i - 1]; + } + let mut temp = 1; + for i in (0..a.len()).rev() { + r[i] *= temp; + temp *= a[i]; + } + + r + } +} diff --git a/src/bin/gray-code.rs b/src/bin/gray-code.rs new file mode 100644 index 00000000..4c02bc80 --- /dev/null +++ b/src/bin/gray-code.rs @@ -0,0 +1,24 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + println!("{:?}", Solution::gray_code(2)); + println!("{:?}", Solution::gray_code(0)); + println!("{:?}", Solution::gray_code(3)); +} + +struct Solution; + +impl Solution { + pub fn gray_code(n: i32) -> Vec { + let mut result = Vec::with_capacity(2i32.pow(n as u32) as usize); + result.push(0); + for i in 0..n as usize { + let x = result.len() - 1; + for j in 0..2usize.pow(i as u32) { + result.push(result[x - j] | (1 << i)); + } + } + + result + } +} diff --git a/src/bin/greatest-common-divisor-of-strings.rs b/src/bin/greatest-common-divisor-of-strings.rs new file mode 100644 index 00000000..197cc6b1 --- /dev/null +++ b/src/bin/greatest-common-divisor-of-strings.rs @@ -0,0 +1,47 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn gcd_of_strings(str1: String, str2: String) -> String { + let mut str1_ = str1.clone(); + let mut str2_ = str2.clone(); + + let mut result = String::new(); + let mut i = 1; + + while i <= str1.len() && i <= str2.len() { + if (i > str1.len() || str1.len() % i == 0) && (i > str2.len() || str2.len() % i == 0) { + let s1 = Self::gdc(str1.as_bytes(), i); + let s2 = Self::gdc(str2.as_bytes(), i); + + if s1 == s2 { + result = String::from_utf8_lossy(s1).to_string() + } + } + + i += 1; + } + + result + } + + fn gdc(s: &[u8], mut i: usize) -> &[u8] { + if i > s.len() { + return &s[0..0]; + } + + let mut start = i; + while start <= s.len() { + if s[start - i..start] != s[0..i] { + return &s[0..0]; + } + + start += i; + } + + &s[0..i] + } +} diff --git a/src/bin/greatest-english-letter-in-upper-and-lower-case.rs b/src/bin/greatest-english-letter-in-upper-and-lower-case.rs new file mode 100644 index 00000000..987edb90 --- /dev/null +++ b/src/bin/greatest-english-letter-in-upper-and-lower-case.rs @@ -0,0 +1,39 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +use std::cmp::max; + +fn main() {} + +struct Solution; + +impl Solution { + pub fn greatest_letter(s: String) -> String { + let mut r = "".to_owned(); + let mut v = vec![0u8; 26]; // 0代表没有,1代表小写,2代表大写 + + for i in 0..s.as_bytes().len() { + let m = s.as_bytes()[i]; + match m { + b'A'..=b'Z' => { + if v[(m - b'A') as usize] == 1 { + r = r.max(s.as_str()[i..i + 1].to_string()); + v[(m - b'A') as usize] = 3; + } else { + v[(m - b'A') as usize] = 2; + } + } + b'a'..=b'z' => { + if v[(m - b'a') as usize] == 2 { + r = r.max(s.as_str()[i..i + 1].to_string().to_uppercase()); + v[(m - b'a') as usize] = 3; + } else { + v[(m - b'a') as usize] = 1; + } + } + _ => unreachable!(), + } + } + + r + } +} diff --git a/src/bin/group-anagrams.rs b/src/bin/group-anagrams.rs new file mode 100644 index 00000000..2a2b3304 --- /dev/null +++ b/src/bin/group-anagrams.rs @@ -0,0 +1,44 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + /// 排序 + pub fn group_anagrams1(strs: Vec) -> Vec> { + let mut hash = std::collections::HashMap::, Vec>::new(); + + for i in strs.into_iter() { + let mut s = i.clone().into_bytes(); + s.sort(); + + hash.entry(s) + .and_modify(|x| x.push(i.clone())) + .or_insert(vec![i]); + } + + hash.into_iter().map(|(_x, y)| y).collect() + } + + // 计算字母出现的个数 + pub fn group_anagrams(strs: Vec) -> Vec> { + let mut hash = std::collections::HashMap::<[u8; 26], Vec>::new(); + + for i in strs.into_iter() { + let mut v = [0; 26]; + + for &j in i.as_bytes() { + v[(j - b'a') as usize] += 1; + } + + if let Some(x) = hash.get_mut(&v) { + x.push(i); + } else { + hash.insert(v, vec![i]); + } + } + + hash.into_iter().map(|(_x, y)| y).collect() + } +} diff --git a/src/bin/grumpy-bookstore-owner.rs b/src/bin/grumpy-bookstore-owner.rs new file mode 100644 index 00000000..e3b094e2 --- /dev/null +++ b/src/bin/grumpy-bookstore-owner.rs @@ -0,0 +1,30 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn max_satisfied(customers: Vec, grumpy: Vec, minutes: i32) -> i32 { + let mut sum = 0; + let mut customers = customers; + + for i in 0..customers.len() { + if grumpy[i] == 0 { + sum += customers[i]; + customers[i] = 0; + } + + if i > 0 { + customers[i] += customers[i - 1]; + } + } + + let mut x = customers[minutes as usize - 1]; + for i in minutes as usize..customers.len() { + x = x.max(customers[i] - customers[i - minutes as usize]); + } + + sum + x + } +} diff --git a/src/bin/gu-piao-de-zui-da-li-run-lcof.rs b/src/bin/gu-piao-de-zui-da-li-run-lcof.rs new file mode 100644 index 00000000..bbf16511 --- /dev/null +++ b/src/bin/gu-piao-de-zui-da-li-run-lcof.rs @@ -0,0 +1,30 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + /// 从后往前遍历, + /// 保存最大的值, + /// 用最大值-当前值就为利润 + /// 保存利润的最大值 + pub fn max_profit(prices: Vec) -> i32 { + let (mut max, mut profit) = (0, 0); + for i in (0..prices.len()).rev() { + if i == prices.len() - 1 { + max = prices[i]; + } else { + if prices[i] > max { + max = prices[i]; + } else { + if max - prices[i] > profit { + profit = max - prices[i]; + } + } + } + } + + profit + } +} diff --git a/src/bin/guess-number-higher-or-lower.rs b/src/bin/guess-number-higher-or-lower.rs index 08a4ad04..181e2339 100644 --- a/src/bin/guess-number-higher-or-lower.rs +++ b/src/bin/guess-number-higher-or-lower.rs @@ -1,3 +1,5 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + struct Solution; impl Solution { @@ -7,12 +9,14 @@ impl Solution { let mut num = 0; loop { // std::thread::sleep(std::time::Duration::from_secs(1)); - let guess_num = start - ( start - num) / 2; + let guess_num = start - (start - num) / 2; let s = guess(guess_num); println!("{}", guess_num); - if s == -1 { // 我猜的较大时 + if s == -1 { + // 我猜的较大时 start = guess_num; - } else if s == 1 { // 我猜的较小时 + } else if s == 1 { + // 我猜的较小时 num = guess_num; } else { break guess_num; diff --git a/src/bin/h-index-ii.rs b/src/bin/h-index-ii.rs new file mode 100644 index 00000000..b5e5ea79 --- /dev/null +++ b/src/bin/h-index-ii.rs @@ -0,0 +1,29 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn h_index(citations: Vec) -> i32 { + // 在区间 (left, right] 内询问 + let n = citations.len(); + let mut left = 0; + let mut right = n; + while left < right { + // 区间不为空 + // 循环不变量: + // left 的回答一定为「是」 + // right+1 的回答一定为「否」 + let mid = (left + right + 1) / 2; // 保证 mid 在二分区间内 + // 引用次数最多的 mid 篇论文,引用次数均 >= mid + if citations[n - mid] >= mid as i32 { + left = mid; // 询问范围缩小到 (mid, right] + } else { + right = mid - 1; // 询问范围缩小到 (left, mid-1] + } + } + // 根据循环不变量,left 现在是最大的回答为「是」的数 + left as i32 + } +} diff --git a/src/bin/h-index.rs b/src/bin/h-index.rs new file mode 100644 index 00000000..56695822 --- /dev/null +++ b/src/bin/h-index.rs @@ -0,0 +1,25 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + println!("{}", Solution::h_index(vec![3, 0, 6, 1, 5])); + println!("{}", Solution::h_index(vec![1])); +} + +struct Solution; + +impl Solution { + pub fn h_index(citations: Vec) -> i32 { + let mut citations = citations; + citations.sort(); + + let mut h = 0; + + for i in (0..citations.len()).rev() { + if citations[i] > h { + h += 1; + } + } + + return h; + } +} diff --git a/src/bin/hPov7L.rs b/src/bin/hPov7L.rs new file mode 100644 index 00000000..81422274 --- /dev/null +++ b/src/bin/hPov7L.rs @@ -0,0 +1,64 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +// Definition for a binary tree node. +#[derive(Debug, PartialEq, Eq)] +pub struct TreeNode { + pub val: i32, + pub left: Option>>, + pub right: Option>>, +} + +impl TreeNode { + #[inline] + pub fn new(val: i32) -> Self { + TreeNode { + val, + left: None, + right: None, + } + } +} +use std::cell::RefCell; +use std::rc::Rc; +use std::vec; +impl Solution { + pub fn largest_values(root: Option>>) -> Vec { + let mut stack = vec![]; + let mut ans = vec![]; + + if root.is_some() { + stack.push(root); + } + + while !stack.is_empty() { + let mut new_stack = vec![]; + let mut max = 0; + + for (i, node) in stack.into_iter().enumerate() { + let node = node.unwrap(); + if node.borrow().left.is_some() { + new_stack.push(node.borrow_mut().left.take()); + } + + if node.borrow().right.is_some() { + new_stack.push(node.borrow_mut().right.take()); + } + + if i == 0 { + max = node.borrow().val; + } else { + max = max.max(node.borrow().val); + } + } + + stack = new_stack; + ans.push(max); + } + + ans + } +} diff --git a/src/bin/hamming-distance.rs b/src/bin/hamming-distance.rs new file mode 100644 index 00000000..ea6cd9e4 --- /dev/null +++ b/src/bin/hamming-distance.rs @@ -0,0 +1,36 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn hamming_distance(x: i32, y: i32) -> i32 { + let mut a = x ^ y; + let mut r = 0; + + while a > 0 { + if a & 1 == 1 { + r += 1; + } + + a >>= 1; + } + + r + } + + /// s & s-1能去掉最后一个1 + /// 比如 s = 0b11001000 + /// 则 s - 1 = 0b11000111 + /// s & s1 = 0b11000000 去掉了第三个1 + pub fn hamming_distance1(x: i32, y: i32) -> i32 { + let (mut s, mut r) = (x ^ y, 0); + while s > 0 { + s = s & (s - 1); + r += 1; + } + + r + } +} diff --git a/src/bin/happy-number.rs b/src/bin/happy-number.rs new file mode 100644 index 00000000..c05e6b3d --- /dev/null +++ b/src/bin/happy-number.rs @@ -0,0 +1,33 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + println!("{}", Solution::is_happy(19)); + println!("{}", Solution::is_happy(2)); +} + +struct Solution; + +impl Solution { + pub fn is_happy(n: i32) -> bool { + let mut n = n; + + let mut h = std::collections::HashSet::new(); + loop { + let mut r = 0; + while n > 0 { + r += (n % 10).pow(2); + n /= 10; + } + if r == 1 { + return true; + } + + if h.contains(&r) { + return false; + } + + h.insert(r); + n = r; + } + } +} diff --git a/src/bin/harshad-number.rs b/src/bin/harshad-number.rs new file mode 100644 index 00000000..c0c248c7 --- /dev/null +++ b/src/bin/harshad-number.rs @@ -0,0 +1,23 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn sum_of_the_digits_of_harshad_number(x: i32) -> i32 { + let mut sum = 0; + let mut x1 = x; + + while x1 > 0 { + sum += x1 % 10; + x1 /= 10; + } + + if x % sum == 0 { + sum + } else { + -1 + } + } +} diff --git a/src/bin/he-bing-liang-ge-pai-xu-de-lian-biao-lcof.rs b/src/bin/he-bing-liang-ge-pai-xu-de-lian-biao-lcof.rs new file mode 100644 index 00000000..cfaf6da9 --- /dev/null +++ b/src/bin/he-bing-liang-ge-pai-xu-de-lian-biao-lcof.rs @@ -0,0 +1,54 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +// Definition for singly-linked list. +#[derive(PartialEq, Eq, Clone, Debug)] +pub struct ListNode { + pub val: i32, + pub next: Option>, +} + +impl ListNode { + #[inline] + fn new(val: i32) -> Self { + ListNode { next: None, val } + } +} +impl Solution { + pub fn merge_two_lists( + l1: Option>, + l2: Option>, + ) -> Option> { + let mut r = None; + let mut current = &mut r; + let (mut l1, mut l2) = (l1, l2); + + while l1.is_some() && l2.is_some() { + let v1 = l1.as_ref().unwrap().val; + let v2 = l2.as_ref().unwrap().val; + + if v1 <= v2 { + current.replace(Box::new(ListNode::new(v1))); + l1 = l1.unwrap().next.take(); + } else { + current.replace(Box::new(ListNode::new(v2))); + l2 = l2.unwrap().next.take(); + } + + current = &mut current.as_mut().unwrap().next; + } + + if l1.is_some() { + current.replace(l1.unwrap()); + } + + if l2.is_some() { + current.replace(l2.unwrap()); + } + + r + } +} diff --git a/src/bin/he-wei-sde-lian-xu-zheng-shu-xu-lie-lcof.rs b/src/bin/he-wei-sde-lian-xu-zheng-shu-xu-lie-lcof.rs new file mode 100644 index 00000000..d5cf2c78 --- /dev/null +++ b/src/bin/he-wei-sde-lian-xu-zheng-shu-xu-lie-lcof.rs @@ -0,0 +1,34 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + /// 从i=1,j=2开始,代表连续数组的边界值,sum为3,此时sum是最小的 + /// 如果sum大于target,则说明i需要增加,i增加则sum减少i + /// 如果sum小于target,则说明j需要增加,j增加则sum增加j + /// 当i>=j时,终止 + pub fn find_continuous_sequence(target: i32) -> Vec> { + let (mut i, mut j) = (1, 2); + let mut sum = i + j; + let mut v = vec![]; + while i < j { + if sum == target { + v.push((i..=j).collect()); + sum -= i; + i += 1; + j += 1; + sum += j; + } else if sum > target { + sum -= i; + i += 1; + } else { + j += 1; + sum += j; + } + } + + v + } +} diff --git a/src/bin/he-wei-sde-liang-ge-shu-zi-lcof.rs b/src/bin/he-wei-sde-liang-ge-shu-zi-lcof.rs new file mode 100644 index 00000000..92155187 --- /dev/null +++ b/src/bin/he-wei-sde-liang-ge-shu-zi-lcof.rs @@ -0,0 +1,25 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +use std::vec; + +fn main() {} + +struct Solution; + +impl Solution { + pub fn two_sum(nums: Vec, target: i32) -> Vec { + let (mut i, mut j) = (0, nums.len() - 1); + + while i < j { + if target - nums[i] > nums[j] { + j -= 1; + } else if target - nums[i] < nums[j] { + i += 1; + } else { + break; + } + } + + vec![nums[i], nums[j]] + } +} diff --git a/src/bin/house-robber-ii.rs b/src/bin/house-robber-ii.rs new file mode 100644 index 00000000..14ca49f9 --- /dev/null +++ b/src/bin/house-robber-ii.rs @@ -0,0 +1,58 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn rob(nums: Vec) -> i32 { + let mut max = 0; + for i in 0..nums.len() { + let sum = nums[i]; + let mut hash = std::collections::HashMap::new(); + max = max.max(sum + Self::dp(&nums[..], i, i + 2, &mut hash)); + max = max.max(sum + Self::dp(&nums[..], i, i + 3, &mut hash)); + } + + max + } + + fn dp( + nums: &[i32], + start: usize, + now_index: usize, + hash: &mut std::collections::HashMap, + ) -> i32 { + let now_index = if now_index >= nums.len() { + now_index % nums.len() + } else { + now_index + }; + if (start == 0 && now_index == nums.len() - 1) + || now_index == start + || now_index == start + 1 + || (start != 0 && now_index == start - 1) + || (start == nums.len() - 1 && now_index == 0) + { + return 0; + } + + let index1 = now_index + 2; + let v1 = if let Some(&x) = hash.get(&index1) { + x + } else { + Self::dp(nums, start, index1, hash) + }; + + let index2 = now_index + 3; + let v2 = if let Some(&x) = hash.get(&index2) { + x + } else { + Self::dp(nums, start, index2, hash) + }; + + hash.insert(now_index, nums[now_index] + v1.max(v2)); + + nums[now_index] + v1.max(v2) + } +} diff --git a/src/bin/house-robber-iii.rs b/src/bin/house-robber-iii.rs new file mode 100644 index 00000000..bcb44fe4 --- /dev/null +++ b/src/bin/house-robber-iii.rs @@ -0,0 +1,89 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +// Definition for a binary tree node. +#[derive(Debug, PartialEq, Eq)] +pub struct TreeNode { + pub val: i32, + pub left: Option>>, + pub right: Option>>, +} + +impl TreeNode { + #[inline] + pub fn new(val: i32) -> Self { + TreeNode { + val, + left: None, + right: None, + } + } +} + +use std::cell::RefCell; +use std::rc::Rc; + +impl Solution { + // 每个节点都有偷或者不偷两种情况 + pub fn force_rob(root: Option>>) -> i32 { + Self::r(root.clone(), true).max(Self::r(root.clone(), false)) + } + + pub fn r(root: Option>>, steal: bool) -> i32 { + if root.is_none() { + return 0; + } + + let mut r = 0; + // 如果当前节点可以偷,那么下一个节点就不能偷 + let r1 = if steal { + let mut r1 = root.clone().unwrap().borrow().val; + r1 += Self::r(root.clone().unwrap().borrow().left.clone(), false); + r1 += Self::r(root.clone().unwrap().borrow().right.clone(), false); + r1 + } else { + // 如果当前节点不能偷,那么下一个节点可偷可不偷 + let mut r1 = 0; + r1 += Self::r(root.clone().unwrap().borrow().left.clone(), true) + .max(Self::r(root.clone().unwrap().borrow().left.clone(), false)); + r1 += Self::r(root.clone().unwrap().borrow().right.clone(), true) + .max(Self::r(root.clone().unwrap().borrow().right.clone(), false)); + r1 + }; + + r1 + } + + /// 每个节点都有偷或者不偷两种情况 + /// 先计算高度,然后每个节点都有偷或者不偷两种情况,因此 + /// i节点的最大值 = max(i节点可偷值 + i的子节点不偷的情况下的值, i节点不可偷+i的左子节点可偷+i右子节点可偷, i节点不可偷+i的左子节点不可偷+i右子节点不可偷, i节点不可偷+i的左子节点可偷+i右子节点不可偷, i节点不可偷+i的左子节点不可偷+i右子节点可偷) + /// 因此定义 + pub fn rob(root: Option>>) -> i32 { + let r = Self::r1(root); + + r.0.max(r.1) + } + + /// 设ans为返回值 + /// ans.0表示选择此节点的值 + /// ans.1表示不选择此节点的值 + /// 则: + /// ans.0 = l.1 + r.1 + node.val + /// ans.1 = l.0.max(l.1) + r.0.max(r.1) + fn r1(root: Option>>) -> (i32, i32) { + if root.is_none() { + return (0, 0); + } + + let l = Self::r1(root.clone().unwrap().borrow().left.clone()); + let r = Self::r1(root.clone().unwrap().borrow().right.clone()); + + ( + l.1 + r.1 + root.unwrap().borrow().val, + l.0.max(l.1) + r.0.max(r.1), + ) + } +} diff --git a/src/bin/house-robber.rs b/src/bin/house-robber.rs new file mode 100644 index 00000000..bf80db2b --- /dev/null +++ b/src/bin/house-robber.rs @@ -0,0 +1,46 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn rob(nums: Vec) -> i32 { + if nums.len() == 0 { + return 0; + } + let mut scores = vec![-1; nums.len()]; + Self::dp(&nums, &mut scores); + scores[0] + } + + fn dp(nums: &Vec, scores: &mut Vec) { + let s = scores.len(); + if nums.len() == 1 { + scores[s - 1] = nums[0]; + return; + } + + if nums.len() == 2 { + scores[s - 2] = std::cmp::max(nums[0], nums[1]); + return; + } + + let mut n1 = 0; + if scores[s - nums.len() + 2] != -1 { + n1 = nums[0] + scores[s - nums.len() + 2]; + } else { + Self::dp(&nums[2..].to_vec(), scores); + n1 = nums[0] + scores[s - nums.len() + 2]; + } + + let mut n2 = 0; + if scores[s - nums.len() + 1] != -1 { + n2 = scores[s - nums.len() + 1]; + } else { + Self::dp(&nums[1..].to_vec(), scores); + n2 = scores[s - nums.len() + 1]; + } + scores[s - nums.len()] = std::cmp::max(n1, n2); + } +} diff --git a/src/bin/how-many-numbers-are-smaller-than-the-current-number.rs b/src/bin/how-many-numbers-are-smaller-than-the-current-number.rs new file mode 100644 index 00000000..6f31aff0 --- /dev/null +++ b/src/bin/how-many-numbers-are-smaller-than-the-current-number.rs @@ -0,0 +1,51 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + let s = Solution::smaller_numbers_than_current(vec![8, 1, 2, 2, 3]); + println!("{s:?}"); + + let s = Solution::smaller_numbers_than_current(vec![6, 5, 4, 8]); + println!("{s:?}"); + + let s = Solution::smaller_numbers_than_current(vec![7, 7, 7, 7]); + println!("{s:?}"); +} + +struct Solution; + +impl Solution { + pub fn smaller_numbers_than_current(mut nums: Vec) -> Vec { + let mut result = nums.clone(); + result.sort(); + + 'out_loop: for i in nums.iter_mut() { + if *i <= result[0] { + *i = 0; + } else if *i > result[result.len() - 1] { + *i = result.len() as i32; + } else { + let (mut start, mut end) = (0, result.len() - 1); + let mut middle = (start + end) / 2; + + while start <= end { + if *i > result[middle] { + start = middle + 1; + } else if *i == result[middle] { + if middle == 0 || result[middle - 1] < *i { + *i = middle as i32; + continue 'out_loop; + } else if result[middle - 1] == *i { + end = middle - 1; + } else { + start = middle + 1; + } + } else { + end = middle - 1; + } + middle = (start + end) / 2; + } + } + } + nums + } +} diff --git a/src/bin/html-entity-parser.rs b/src/bin/html-entity-parser.rs new file mode 100644 index 00000000..dbec471d --- /dev/null +++ b/src/bin/html-entity-parser.rs @@ -0,0 +1,39 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn entity_parser(text: String) -> String { + let mut string = String::new(); + let mut s = &text[..]; + + while !s.is_empty() { + if s.starts_with(""") { + string.push('"'); + s = &s[6..] + } else if s.starts_with("&apos") { + string.push('\''); + s = &s[6..] + } else if s.starts_with("&") { + string.push('&'); + s = &s[5..] + } else if s.starts_with(">") { + string.push('>'); + s = &s[4..] + } else if s.starts_with("<") { + string.push('<'); + s = &s[4..] + } else if s.starts_with("⁄") { + string.push('/'); + s = &s[7..] + } else { + string.push_str(&s[0..1]); + s = &s[1..]; + } + } + + string + } +} diff --git a/src/bin/iIQa4I.rs b/src/bin/iIQa4I.rs new file mode 100644 index 00000000..fee60fe8 --- /dev/null +++ b/src/bin/iIQa4I.rs @@ -0,0 +1,33 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() { + assert_eq!( + Solution::daily_temperatures(vec![73, 74, 75, 71, 69, 72, 76, 73]), + vec![1, 1, 4, 2, 1, 1, 0, 0] + ) +} + +struct Solution; + +impl Solution { + /// 单调递减栈,保存下标 + pub fn daily_temperatures(temperatures: Vec) -> Vec { + let mut stack = vec![]; + let mut ans = vec![0; temperatures.len()]; + + for i in 0..temperatures.len() { + while !stack.is_empty() { + if temperatures[stack[stack.len() - 1]] < temperatures[i] { + ans[stack[stack.len() - 1]] = (i - stack[stack.len() - 1]) as i32; + stack.pop(); + } else { + break; + } + } + + stack.push(i); + } + + ans + } +} diff --git a/src/bin/implement-magic-dictionary.rs b/src/bin/implement-magic-dictionary.rs new file mode 100644 index 00000000..9f432876 --- /dev/null +++ b/src/bin/implement-magic-dictionary.rs @@ -0,0 +1,95 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +/** + * `&self` means the method takes an immutable reference. + * If you need a mutable reference, change it to `&mut self` instead. + */ + +/** + * Your MagicDictionary object will be instantiated and called as such: + * let obj = MagicDictionary::new(); + * obj.build_dict(dictionary); + * let ret_2: bool = obj.search(searchWord); + */ + +#[derive(Clone)] +struct Tier { + data: Vec>>, + is_end: bool, +} + +impl Tier { + fn new() -> Self { + Tier { + data: vec![None; 26], + is_end: false, + } + } + + fn insert(&mut self, data: &[u8]) { + if data.is_empty() { + return; + } + + let mut node = self; + + for i in data { + let index = (i - b'a') as usize; + if node.data[index].is_none() { + node.data[index] = Some(Box::new(Tier::new())); + } + node = node.data[index].as_mut().unwrap(); + } + + node.is_end = true; + } + + /// flag为true表示已经变换过 + fn search(&self, data: &[u8], flag: bool) -> bool { + if data.is_empty() { + return self.is_end && flag; + } + let index = (data[0] - b'a') as usize; + if let Some(x) = self.data[index].as_ref() { + if x.search(&data[1..], flag | false) { + return true; + } + } + + if !flag { + for i in (0..26).filter(|&x| x != index) { + if let Some(x) = self.data[i].as_ref() { + if x.search(&data[1..], true) { + return true; + } + } + } + } + + false + } +} + +struct MagicDictionary { + tier: Tier, +} + +impl MagicDictionary { + fn new() -> Self { + Self { tier: Tier::new() } + } + + fn build_dict(&mut self, dictionary: Vec) { + dictionary + .into_iter() + .for_each(|x| self.tier.insert(x.as_bytes())); + } + + fn search(&self, search_word: String) -> bool { + self.tier.search(search_word.as_bytes(), false) + } +} diff --git a/src/bin/implement-queue-using-stacks.rs b/src/bin/implement-queue-using-stacks.rs new file mode 100644 index 00000000..22efe3c0 --- /dev/null +++ b/src/bin/implement-queue-using-stacks.rs @@ -0,0 +1,51 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +/** + * Your MyQueue object will be instantiated and called as such: + * let obj = MyQueue::new(); + * obj.push(x); + * let ret_2: i32 = obj.pop(); + * let ret_3: i32 = obj.peek(); + * let ret_4: bool = obj.empty(); + */ +struct MyQueue { + data: Vec, +} + +/** + * `&self` means the method takes an immutable reference. + * If you need a mutable reference, change it to `&mut self` instead. + */ +impl MyQueue { + /** Initialize your data structure here. */ + fn new() -> Self { + Self { data: vec![] } + } + + /** Push element x to the back of queue. */ + fn push(&mut self, x: i32) { + self.data.push(x); + } + + /** Removes the element from in front of queue and returns that element. */ + fn pop(&mut self) -> i32 { + let data = self.peek(); + self.data = self.data[1..].to_vec(); + data + } + + /** Get the front element. */ + fn peek(&mut self) -> i32 { + let data = self.data[0]; + data + } + + /** Returns whether the queue is empty. */ + fn empty(&self) -> bool { + self.data.len() == 0 + } +} diff --git a/src/bin/implement-rand10-using-rand7.rs b/src/bin/implement-rand10-using-rand7.rs new file mode 100644 index 00000000..18334e05 --- /dev/null +++ b/src/bin/implement-rand10-using-rand7.rs @@ -0,0 +1,30 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +/** + * The rand7() API is already defined for you. + * @return a random integer in the range 1 to 7 + * fn rand7() -> i32; + */ + +fn rand7() -> i32 { + unimplemented!() +} + +impl Solution { + pub fn resolve() -> i32 { + (rand7() - 1) * 7 + rand7() - 1 + } + + pub fn rand10() -> i32 { + let mut pos = Self::resolve(); + while pos >= 40 { + pos = Self::resolve(); + } + + pos % 10 + 1 + } +} diff --git a/src/bin/implement-stack-using-queues.rs b/src/bin/implement-stack-using-queues.rs new file mode 100644 index 00000000..9b330aa3 --- /dev/null +++ b/src/bin/implement-stack-using-queues.rs @@ -0,0 +1,50 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +/** + * Your MyStack object will be instantiated and called as such: + * let obj = MyStack::new(); + * obj.push(x); + * let ret_2: i32 = obj.pop(); + * let ret_3: i32 = obj.top(); + * let ret_4: bool = obj.empty(); + */ +struct MyStack { + data: std::cell::RefCell>, +} + +/** + * `&self` means the method takes an immutable reference. + * If you need a mutable reference, change it to `&mut self` instead. + */ +impl MyStack { + /** Initialize your data structure here. */ + fn new() -> Self { + Self { + data: std::cell::RefCell::new(Vec::new()), + } + } + + /** Push element x onto stack. */ + fn push(&self, x: i32) { + self.data.borrow_mut().push(x); + } + + /** Removes the element on top of the stack and returns that element. */ + fn pop(&self) -> i32 { + self.data.borrow_mut().pop().unwrap() + } + + /** Get the top element. */ + fn top(&self) -> i32 { + *self.data.borrow_mut().last().unwrap() + } + + /** Returns whether the stack is empty. */ + fn empty(&self) -> bool { + self.data.borrow().len() == 0 + } +} diff --git a/src/bin/implement-strstr.rs b/src/bin/implement-strstr.rs new file mode 100644 index 00000000..9a1e6d41 --- /dev/null +++ b/src/bin/implement-strstr.rs @@ -0,0 +1,87 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + println!( + "{:?}", + Solution::prefix_table("aabaabaaa".to_string().as_bytes()) + ); + println!( + "{:?}", + Solution::prefix_table("abcdabca".to_string().as_bytes()) + ); + println!( + "{:?}", + Solution::prefix_table("ababcaabc".to_string().as_bytes()) + ); + println!( + "{:?}", + Solution::prefix_table("aabaaac".to_string().as_bytes()) + ); + println!( + "{}", + Solution::str_str("abxabcabcaby".to_string(), "abcaby".to_string()) + ); + println!( + "{}", + Solution::str_str("ababcaababcaabc".to_string(), "ababcaabc".to_string()) + ); + println!( + "{}", + Solution::str_str("aabaaabaaac".to_string(), "aabaaac".to_string()) + ); +} + +struct Solution; + +impl Solution { + pub fn str_str(haystack: String, needle: String) -> i32 { + if needle.len() == 0 { + return 0; + } + let (nums, s) = (needle.as_bytes(), haystack.as_bytes()); + let next = Self::prefix_table(&nums[..]); + let (mut i, mut j) = (0, 0); // i是s的下标,j是next的下标 + while i < s.len() { + if s[i] == nums[j] { + if j == nums.len() - 1 { + return (i - j) as i32; + } + i += 1; + j += 1; + } else { + if j != 0 { + j = next[j - 1]; + } else { + i += 1; + } + } + } + -1 + } + + /// 获取到前缀表 + fn prefix_table(nums: &[u8]) -> Vec { + let mut tables = vec![0usize; nums.len()]; + tables[0] = 0; // 第一个元素的前缀表为0 + let mut j = 0; + for i in 1..nums.len() { + if nums[j] == nums[i] { + tables[i] = tables[i - 1] + 1; + j += 1; + } else { + while j > 0 { + j = tables[j - 1]; + if nums[j] == nums[i] { + tables[i] = tables[j] + 1; + j += 1; + break; + } else { + tables[i] = 0; + } + } + } + } + + tables + } +} diff --git a/src/bin/implement-trie-prefix-tree.rs b/src/bin/implement-trie-prefix-tree.rs new file mode 100644 index 00000000..76878cfa --- /dev/null +++ b/src/bin/implement-trie-prefix-tree.rs @@ -0,0 +1,83 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +struct Trie { + /// 截止到此字母是否为一个单词 + is_word: bool, + /// 树的节点 + nodes: std::collections::HashMap, +} + +/** + * `&self` means the method takes an immutable reference. + * If you need a mutable reference, change it to `&mut self` instead. + */ +impl Trie { + /** Initialize your data structure here. */ + fn new() -> Self { + Self { + is_word: false, + nodes: std::collections::HashMap::with_capacity(26), + } + } + + /** Inserts a word into the trie. */ + fn insert(&mut self, word: String) { + self.insert_bytes(word.as_bytes()); + } + + fn insert_bytes(&mut self, words: &[u8]) { + if words.len() < 1 { + return; + } + + let i = words[0]; + let is_last = words.len() == 1; + if let Some(x) = self.nodes.get_mut(&i) { + if is_last { + x.is_word = true; + } + x.insert_bytes(&words[1..]); + } else { + let mut x = Self::new(); + if is_last { + x.is_word = true; + } + x.insert_bytes(&words[1..]); + self.nodes.insert(i, x); + } + } + + /** Returns if the word is in the trie. */ + fn search(&self, word: String) -> bool { + self.search_bytes(word.as_bytes(), false) + } + + fn search_bytes(&self, words: &[u8], is_prefix: bool) -> bool { + if words.len() == 0 { + return is_prefix || self.is_word; + } + + if let Some(x) = self.nodes.get(&words[0]) { + x.search_bytes(&words[1..], is_prefix) + } else { + false + } + } + + /** Returns if there is any word in the trie that starts with the given prefix. */ + fn starts_with(&self, prefix: String) -> bool { + self.search_bytes(prefix.as_bytes(), true) + } +} + +// /** +// * Your Trie object will be instantiated and called as such: +// * let obj = Trie::new(); +// * obj.insert(word); +// * let ret_2: bool = obj.search(word); +// * let ret_3: bool = obj.starts_with(prefix); +// */ diff --git a/src/bin/increasing-decreasing-string.rs b/src/bin/increasing-decreasing-string.rs new file mode 100644 index 00000000..2893451b --- /dev/null +++ b/src/bin/increasing-decreasing-string.rs @@ -0,0 +1,40 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn sort_string(mut s: String) -> String { + let mut count = [0; 26]; + for &i in s.as_bytes() { + count[(i - b'a') as usize] += 1; + } + let mut slice = unsafe { s.as_bytes_mut() }; + let mut start = 0; + let mut flag = false; // true为选最大,false为选最小 + while start < slice.len() { + if !flag { + for i in 0..26 { + if count[i] > 0 { + slice[start] = i as u8 + b'a'; + count[i] -= 1; + start += 1; + } + } + } else { + for i in (0..26).rev() { + if count[i] > 0 { + slice[start] = i as u8 + b'a'; + count[i] -= 1; + start += 1; + } + } + } + + flag = !flag; + } + + s + } +} diff --git a/src/bin/increasing-triplet-subsequence.rs b/src/bin/increasing-triplet-subsequence.rs new file mode 100644 index 00000000..44ee4b1b --- /dev/null +++ b/src/bin/increasing-triplet-subsequence.rs @@ -0,0 +1,27 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn increasing_triplet(nums: Vec) -> bool { + if nums.len() < 3 { + return false; + } + + let (mut first, mut second) = (nums[0], i32::MAX); + + for &i in nums[1..].into_iter() { + if i > second { + return true; + } else if i > first { + second = i; + } else { + first = i; + } + } + + false + } +} diff --git a/src/bin/increment-submatrices-by-one.rs b/src/bin/increment-submatrices-by-one.rs new file mode 100644 index 00000000..59ec0637 --- /dev/null +++ b/src/bin/increment-submatrices-by-one.rs @@ -0,0 +1,40 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + /// 二维差分 + /// 开始的下标+1,结尾+1的下标-1 + /// 例如有数组 vec![0,0,0,0,0,0,0,0],如果把[1,3]的下标都加一,因此我们有差分数组vec![0,1,0,0,-1,0,0,0] + /// 然后每个下标为前缀和 + pub fn range_add_queries(n: i32, queries: Vec>) -> Vec> { + let mut diff = vec![vec![0; n as usize + 2]; n as usize + 2]; + + for query in queries { + let (r1, c1, r2, c2) = ( + query[0] as usize, + query[1] as usize, + query[2] as usize, + query[3] as usize, + ); + + diff[r1 + 1][c1 + 1] += 1; + diff[r1 + 1][c2 + 2] -= 1; + diff[r2 + 2][c1 + 1] -= 1; + diff[r2 + 2][c2 + 2] += 1; + } + + for i in 1..=n as usize { + for j in 1..=n as usize { + diff[i][j] += diff[i][j - 1] + diff[i - 1][j] - diff[i - 1][j - 1]; + } + } + + diff[1..n as usize + 1] + .into_iter() + .map(|x| x[1..n as usize + 1].to_vec()) + .collect() + } +} diff --git a/src/bin/incremental-memory-leak.rs b/src/bin/incremental-memory-leak.rs new file mode 100644 index 00000000..6e598472 --- /dev/null +++ b/src/bin/incremental-memory-leak.rs @@ -0,0 +1,27 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +use std::vec; + +fn main() {} + +struct Solution; + +impl Solution { + pub fn mem_leak(mut memory1: i32, mut memory2: i32) -> Vec { + let mut t = 1; + + loop { + if t > memory1 && t > memory2 { + return vec![t, memory1, memory2]; + } + + if memory2 > memory1 { + memory2 -= t; + } else { + memory1 -= t; + } + + t += 1; + } + } +} diff --git a/src/bin/insert-delete-getrandom-o1-duplicates-allowed.rs b/src/bin/insert-delete-getrandom-o1-duplicates-allowed.rs new file mode 100644 index 00000000..a7db0ddc --- /dev/null +++ b/src/bin/insert-delete-getrandom-o1-duplicates-allowed.rs @@ -0,0 +1,102 @@ +#![allow(dead_code, unused, unused_variables)] + +use rand::Rng; + +fn main() { + let mut r = RandomizedCollection::new(); + assert!(r.insert(1)); + assert!(!r.insert(1)); + assert!(r.insert(2)); + assert!(r.remove(1)); + println!("{}", r.get_random()); + println!("{}", r.get_random()); + println!("{}", r.get_random()); + println!("{}", rand::thread_rng().gen_range(0..10)); + println!("{}", rand::thread_rng().gen_range(0..10)); + println!("{}", rand::thread_rng().gen_range(0..10)); + println!("{}", rand::thread_rng().gen_range(0..10)); +} + +/** + * Your RandomizedCollection object will be instantiated and called as such: + * let obj = RandomizedCollection::new(); + * let ret_1: bool = obj.insert(val); + * let ret_2: bool = obj.remove(val); + * let ret_3: i32 = obj.get_random(); + */ +struct RandomizedCollection { + data: Vec, + indexes: std::collections::HashMap>, +} + +/** + * `&self` means the method takes an immutable reference. + * If you need a mutable reference, change it to `&mut self` instead. + */ +impl RandomizedCollection { + /** Initialize your data structure here. */ + fn new() -> Self { + Self { + data: Vec::new(), + indexes: std::collections::HashMap::new(), + } + } + + /** Inserts a value to the collection. Returns true if the collection did not already contain the specified element. */ + fn insert(&mut self, val: i32) -> bool { + let has = self.indexes.get(&val).is_some(); + self.data.push(val); + let index = self.data.len() - 1; + self.indexes + .entry(val) + .and_modify(|i| { + i.insert(index, ()); + }) + .or_insert_with(|| { + let mut h = std::collections::HashMap::new(); + h.insert(index, ()); + h + }); + + !has + } + + /** Removes a value from the collection. Returns true if the collection contained the specified element. */ + fn remove(&mut self, val: i32) -> bool { + if self.indexes.get(&val).is_none() { + return false; + } + + let index = { + let i = *self.indexes.get(&val).unwrap().keys().next().unwrap(); + self.indexes.get_mut(&val).unwrap().remove(&i); + i + }; + let l = self.data.len() - 1; + let last = self.data[l]; + self.data.swap(index, l); + + if l != index { + self.indexes.entry(last).and_modify(|x| { + x.remove(&l); + x.insert(index, ()); + }); + } + + self.data.pop(); + + if self.indexes.get(&val).unwrap().is_empty() { + self.indexes.remove(&val); + } + + true + } + + /** Get a random element from the collection. */ + fn get_random(&self) -> i32 { + use rand::Rng; + let mut rng = rand::thread_rng(); + let index = rng.gen_range(0..self.data.len()); + self.data[index] + } +} diff --git a/src/bin/insert-delete-getrandom-o1.rs b/src/bin/insert-delete-getrandom-o1.rs new file mode 100644 index 00000000..c7d46cae --- /dev/null +++ b/src/bin/insert-delete-getrandom-o1.rs @@ -0,0 +1,53 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +/** + * Your RandomizedSet object will be instantiated and called as such: + * let obj = RandomizedSet::new(); + * let ret_1: bool = obj.insert(val); + * let ret_2: bool = obj.remove(val); + * let ret_3: i32 = obj.get_random(); + */ +struct RandomizedSet { + set: std::cell::RefCell>, +} + +/** + * `&self` means the method takes an immutable reference. + * If you need a mutable reference, change it to `&mut self` instead. + */ +impl RandomizedSet { + /** Initialize your data structure here. */ + fn new() -> Self { + Self { + set: std::cell::RefCell::new(std::collections::HashSet::default()), + } + } + + /** Inserts a value to the set. Returns true if the set did not already contain the specified element. */ + fn insert(&self, val: i32) -> bool { + self.set.borrow_mut().insert(val) + } + + /** Removes a value from the set. Returns true if the set contained the specified element. */ + fn remove(&self, val: i32) -> bool { + self.set.borrow_mut().remove(&val) + } + + /** Get a random element from the set. */ + fn get_random(&self) -> i32 { + use rand::Rng; + let mut rng = rand::thread_rng(); + let s = rng.gen_range(0..self.set.borrow().len()); + for (i, v) in self.set.borrow().iter().enumerate() { + if i == s { + return *v; + } + } + + 0 + } +} diff --git a/src/bin/insert-greatest-common-divisors-in-linked-list.rs b/src/bin/insert-greatest-common-divisors-in-linked-list.rs new file mode 100644 index 00000000..e6f38ad0 --- /dev/null +++ b/src/bin/insert-greatest-common-divisors-in-linked-list.rs @@ -0,0 +1,73 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +// Definition for singly-linked list. +#[derive(PartialEq, Eq, Clone, Debug)] +pub struct ListNode { + pub val: i32, + pub next: Option>, +} + +impl ListNode { + #[inline] + fn new(val: i32) -> Self { + ListNode { next: None, val } + } +} + +impl Solution { + pub fn insert_greatest_common_divisors(head: Option>) -> Option> { + let mut h = ListNode { val: 0, next: None }; + let mut current = &mut h.next; + let mut head = head; + let mut next = head.as_mut().and_then(|x| x.next.take()); + + loop { + match (head, next) { + (Some(mut x), Some(mut y)) => { + next = y.next.take(); + let (max, min) = if x.val > y.val { + (x.val, y.val) + } else { + (y.val, x.val) + }; + + let gdc = Self::gdc(max, min); + current.insert(x); + current = &mut current.as_mut().unwrap().next; + current.insert(Box::new(ListNode::new(gdc))); + current = &mut current.as_mut().unwrap().next; + head = Some(y); + } + (Some(x), None) => { + current.insert(x); + break; + } + _ => break, + } + } + + h.next.take() + } + + /// 辗转相除法, 又名欧几里德算法(Euclidean algorithm),是求最大公约数的一种方法。方法是: + /// 用较大数除以较小数,再用出现的余数(第一余数)去除除数,再用出现的余数(第二余数)去除第一余数, + /// 如此反复,直到最后余数是0为止。那么最后的除数就是这两个数的最大公约数。 + pub fn gdc(max: i32, min: i32) -> i32 { + let r = max % min; + if r == 0 { + return min; + } + + Self::gdc(min, r) + } +} + +#[test] +fn test_gdc() { + assert_eq!(6, Solution::gdc(30, 18)); + assert_eq!(6, Solution::gdc(123456, 7890)); +} diff --git a/src/bin/insert-interval.rs b/src/bin/insert-interval.rs new file mode 100644 index 00000000..c6991585 --- /dev/null +++ b/src/bin/insert-interval.rs @@ -0,0 +1,56 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn insert(intervals: Vec>, new_interval: Vec) -> Vec> { + let mut result = vec![]; + if intervals.len() == 0 { + result.push(new_interval); + return result; + } + let (mut index0, mut index1) = (new_interval[0], new_interval[1]); + + if intervals[0][0] > new_interval[1] { + result.push(new_interval); + result.extend(intervals.into_iter()); + return result; + } + + if intervals[intervals.len() - 1][1] < new_interval[0] { + result.extend(intervals.into_iter()); + result.push(new_interval); + return result; + } + + let mut flag = false; + + for i in intervals.into_iter() { + if i[1] < index0 { + result.push(i); + } else if i[0] > index1 { + if !flag { + result.push(vec![index0, index1]); + flag = true; + } + result.push(i); + } else { + index0 = i[0].min(index0); + index1 = i[1].max(index1); + + if !flag { + result.push(vec![index0, index1]); + flag = true; + } else { + let l = result.len() - 1; + result[l][0] = index0; + result[l][1] = index1; + } + } + } + + result + } +} diff --git a/src/bin/insert-into-a-binary-search-tree.rs b/src/bin/insert-into-a-binary-search-tree.rs new file mode 100644 index 00000000..62ec2def --- /dev/null +++ b/src/bin/insert-into-a-binary-search-tree.rs @@ -0,0 +1,49 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +// Definition for a binary tree node. +#[derive(Debug, PartialEq, Eq)] +pub struct TreeNode { + pub val: i32, + pub left: Option>>, + pub right: Option>>, +} + +impl TreeNode { + #[inline] + pub fn new(val: i32) -> Self { + TreeNode { + val, + left: None, + right: None, + } + } +} + +use std::cell::RefCell; +use std::rc::Rc; + +impl Solution { + pub fn insert_into_bst( + root: Option>>, + val: i32, + ) -> Option>> { + if root.is_none() { + return Some(Rc::new(RefCell::new(TreeNode::new(val)))); + } + let v = root.as_ref().unwrap().borrow().val; + + if v > val { + let left = root.as_ref().unwrap().borrow_mut().left.take(); + root.as_ref().unwrap().borrow_mut().left = Self::insert_into_bst(left, val); + } else { + let right = root.as_ref().unwrap().borrow_mut().right.take(); + root.as_ref().unwrap().borrow_mut().right = Self::insert_into_bst(right, val); + } + + root + } +} diff --git a/src/bin/insufficient-nodes-in-root-to-leaf-paths.rs b/src/bin/insufficient-nodes-in-root-to-leaf-paths.rs new file mode 100644 index 00000000..4268ad85 --- /dev/null +++ b/src/bin/insufficient-nodes-in-root-to-leaf-paths.rs @@ -0,0 +1,71 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +// Definition for a binary tree node. +#[derive(Debug, PartialEq, Eq)] +pub struct TreeNode { + pub val: i32, + pub left: Option>>, + pub right: Option>>, +} + +impl TreeNode { + #[inline] + pub fn new(val: i32) -> Self { + TreeNode { + val, + left: None, + right: None, + } + } +} + +use std::cell::RefCell; +use std::rc::Rc; + +impl Solution { + pub fn sufficient_subset( + root: Option>>, + limit: i32, + ) -> Option>> { + if root.is_none() { + return None; + } + + { + if root.as_ref().unwrap().borrow().left.is_none() + && root.as_ref().unwrap().borrow().right.is_none() + { + return if root.as_ref().unwrap().borrow().val < limit { + None + } else { + root + }; + } + } + + let val = root.as_ref().unwrap().borrow_mut().val; + + let left = + Self::sufficient_subset(root.as_ref().unwrap().borrow_mut().left.take(), limit - val); + root.as_ref().unwrap().borrow_mut().left = left; + + let right = Self::sufficient_subset( + root.as_ref().unwrap().borrow_mut().right.take(), + limit - val, + ); + root.as_ref().unwrap().borrow_mut().right = right; + + { + let r = root.as_ref().unwrap().borrow(); + if r.left.is_none() && r.right.is_none() { + return None; + } + } + + root + } +} diff --git a/src/bin/integer-replacement.rs b/src/bin/integer-replacement.rs new file mode 100644 index 00000000..2961cb81 --- /dev/null +++ b/src/bin/integer-replacement.rs @@ -0,0 +1,33 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + println!("{}", Solution::integer_replacement(2147483647)); +} + +struct Solution; + +impl Solution { + pub fn integer_replacement(n: i32) -> i32 { + let mut h = std::collections::HashMap::new(); + Self::f(n as i64, &mut h) as i32 + } + + fn f(n: i64, h: &mut std::collections::HashMap) -> i64 { + if n == 1 { + return 0; + } + + if let Some(x) = h.get(&n) { + return *x; + } + + let m = if n % 2 == 0 { + Self::f(n / 2, h) + 1 + } else { + Self::f(n - 1, h).min(Self::f(n + 1, h)) + 1 + }; + + h.insert(n, m); + m + } +} diff --git a/src/bin/integer-to-roman.rs b/src/bin/integer-to-roman.rs new file mode 100644 index 00000000..c5b1018b --- /dev/null +++ b/src/bin/integer-to-roman.rs @@ -0,0 +1,90 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + Solution::int_to_roman(23134); +} + +struct Solution; + +impl Solution { + /// 常规解法 + pub fn int_to_roman1(num: i32) -> String { + let mut v = vec![]; + let (mut num, mut n) = (num, 1); + while num != 0 { + v.push((num % 10) * n); + n *= 10; + num /= 10; + } + + let mut result = String::new(); + while !v.is_empty() { + let x = v.pop().unwrap(); + match x { + 1000..=3000 => result.push_str("M".repeat((x / 1000) as usize).as_str()), + 100..=300 => result.push_str("C".repeat((x / 100) as usize).as_str()), + 400 => result.push_str("CD"), + 500 => result.push_str("D"), + 600..=800 => { + result.push_str("D"); + result.push_str("C".repeat(((x - 500) / 100) as usize).as_str()); + } + 900 => result.push_str("CM"), + 10..=30 => result.push_str("X".repeat((x / 100) as usize).as_str()), + 40 => result.push_str("XL"), + 50 => result.push_str("L"), + 60..=80 => { + result.push_str("L"); + result.push_str("C".repeat(((x - 500) / 100) as usize).as_str()); + } + 90 => result.push_str("XC"), + 1..=3 => result.push_str("I".repeat((x / 100) as usize).as_str()), + 4 => result.push_str("IV"), + 5 => result.push_str("V"), + 6..=8 => { + result.push_str("V"); + result.push_str("I".repeat(((x - 500) / 100) as usize).as_str()); + } + 9 => result.push_str("IX"), + _ => (), + } + } + + result + } + + pub fn int_to_roman(num: i32) -> String { + let mut stack = vec![ + (1, "I"), + (4, "IV"), + (5, "V"), + (9, "IX"), + (10, "X"), + (40, "XL"), + (50, "L"), + (90, "XC"), + (100, "C"), + (400, "CD"), + (500, "D"), + (900, "CM"), + (1000, "M"), + ]; + let mut num = num; + let mut result = String::new(); + + while !stack.is_empty() { + match stack.last() { + Some(x) if x.0 > num => { + stack.pop(); + } + Some(x) => { + result.push_str(x.1); + num -= x.0; + } + _ => (), + } + } + + result + } +} diff --git a/src/bin/intersection-of-two-arrays-ii.rs b/src/bin/intersection-of-two-arrays-ii.rs new file mode 100644 index 00000000..87c1fa0f --- /dev/null +++ b/src/bin/intersection-of-two-arrays-ii.rs @@ -0,0 +1,29 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn intersect(nums1: Vec, nums2: Vec) -> Vec { + let mut v = vec![]; + let (mut nums1, mut nums2) = (nums1, nums2); + nums1.sort(); + nums2.sort(); + let (mut i, mut j) = (0, 0); + + while i < nums1.len() && j < nums2.len() { + if nums1[i] == nums2[j] { + v.push(nums2[j]); + i += 1; + j += 1; + } else if nums1[i] < nums2[j] { + i += 1; + } else { + j += 1; + } + } + + v + } +} diff --git a/src/bin/intersection-of-two-arrays.rs b/src/bin/intersection-of-two-arrays.rs new file mode 100644 index 00000000..7be3aa5d --- /dev/null +++ b/src/bin/intersection-of-two-arrays.rs @@ -0,0 +1,32 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn intersection(nums1: Vec, nums2: Vec) -> Vec { + let mut nums1 = nums1; + let mut nums2 = nums2; + nums1.sort(); + nums2.sort(); + + let mut result = vec![]; + + let (mut index1, mut index2) = (0, 0); + while index1 < nums1.len() && index2 < nums2.len() { + if nums1[index1] == nums2[index2] { + if result.len() == 0 || nums1[index1] != *result.last().unwrap() { + result.push(nums1[index1]); + } + index1 += 1; + index2 += 1; + } else if nums1[index1] > nums2[index2] { + index2 += 1; + } else { + index1 += 1; + } + } + result + } +} diff --git a/src/bin/invert-binary-tree.rs b/src/bin/invert-binary-tree.rs new file mode 100644 index 00000000..222bd62b --- /dev/null +++ b/src/bin/invert-binary-tree.rs @@ -0,0 +1,43 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +// Definition for a binary tree node. +#[derive(Debug, PartialEq, Eq)] +pub struct TreeNode { + pub val: i32, + pub left: Option>>, + pub right: Option>>, +} + +impl TreeNode { + #[inline] + pub fn new(val: i32) -> Self { + TreeNode { + val, + left: None, + right: None, + } + } +} + +use std::cell::RefCell; +use std::rc::Rc; + +impl Solution { + pub fn invert_tree(root: Option>>) -> Option>> { + if root.is_none() { + return None; + } + + let mut root = root; + let left = root.as_ref().unwrap().borrow_mut().left.take(); + let right = root.as_ref().unwrap().borrow_mut().right.take(); + root.as_mut().unwrap().borrow_mut().right = Self::invert_tree(left); + root.as_mut().unwrap().borrow_mut().left = Self::invert_tree(right); + + root + } +} diff --git a/src/bin/is-subsequence.rs b/src/bin/is-subsequence.rs new file mode 100644 index 00000000..d5bd74b9 --- /dev/null +++ b/src/bin/is-subsequence.rs @@ -0,0 +1,27 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn is_subsequence(s: String, t: String) -> bool { + let (mut i, mut j) = (0, 0); // i: s'index, j: t'index + let (s, t) = (s.as_bytes(), t.as_bytes()); + loop { + if i == s.len() { + return true; + } + if j == t.len() { + break; + } + + if s[i] == t[j] { + i += 1; + } + j += 1; + } + + return false; + } +} diff --git a/src/bin/isomorphic-strings.rs b/src/bin/isomorphic-strings.rs new file mode 100644 index 00000000..fa78bf70 --- /dev/null +++ b/src/bin/isomorphic-strings.rs @@ -0,0 +1,37 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn is_isomorphic(s: String, t: String) -> bool { + if s.len() != t.len() { + return false; + } + + let mut h1 = std::collections::HashMap::::new(); + let mut h2 = std::collections::HashMap::::new(); + let (s, t) = (s.as_bytes(), t.as_bytes()); + for i in 0..s.len() { + let (mut r1, mut r2) = (false, false); + if let Some(x) = h1.get(&s[i]) { + r1 = *x != t[i]; + } else { + h1.insert(s[i], t[i]); + } + + if let Some(x) = h2.get(&t[i]) { + r2 = *x != s[i]; + } else { + h2.insert(t[i], s[i]); + } + + if r1 || r2 { + return false; + } + } + + true + } +} diff --git a/src/bin/jewels-and-stones.rs b/src/bin/jewels-and-stones.rs new file mode 100644 index 00000000..ab7a7c5f --- /dev/null +++ b/src/bin/jewels-and-stones.rs @@ -0,0 +1,15 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn num_jewels_in_stones(jewels: String, stones: String) -> i32 { + let j = jewels + .bytes() + .into_iter() + .collect::>(); + stones.bytes().into_iter().filter(|x| j.contains(x)).count() as i32 + } +} diff --git a/src/bin/ji-qi-ren-de-yun-dong-fan-wei-lcof.rs b/src/bin/ji-qi-ren-de-yun-dong-fan-wei-lcof.rs new file mode 100644 index 00000000..57e0ed92 --- /dev/null +++ b/src/bin/ji-qi-ren-de-yun-dong-fan-wei-lcof.rs @@ -0,0 +1,57 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() { + println!("{}", Solution::moving_count(2, 3, 1)); + println!("{}", Solution::moving_count(3, 1, 0)); + println!("{}", Solution::moving_count(3, 2, 17)); + println!("{}", Solution::moving_count(16, 8, 4)); +} + +struct Solution; + +impl Solution { + pub fn moving_count(m: i32, n: i32, k: i32) -> i32 { + let mut flags = vec![vec![0; n as usize]; m as usize]; + let mut total = 0; + for i in 0..m as usize { + for j in 0..n as usize { + if Self::sum(i, j) <= k + && ((i == 0 && j == 0) + || (i > 0 && flags[i - 1][j] == 1) + || (j > 0 && flags[i][j - 1] == 1)) + { + total += 1; + flags[i][j] = 1; + } + } + } + + total + } + + fn sum(mut x: usize, mut y: usize) -> i32 { + let mut sum = 0; + + while x >= 10 { + sum += x % 10; + x /= 10; + } + + sum += x; + + while y >= 10 { + sum += y % 10; + y /= 10; + } + + sum += y; + + sum as i32 + } +} + +#[test] +fn test_sum() { + assert_eq!(Solution::sum(14, 15), 11); + assert_eq!(Solution::sum(101, 230), 7); +} diff --git a/src/bin/jian-sheng-zi-ii-lcof.rs b/src/bin/jian-sheng-zi-ii-lcof.rs new file mode 100644 index 00000000..fefe482c --- /dev/null +++ b/src/bin/jian-sheng-zi-ii-lcof.rs @@ -0,0 +1,36 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() { + println!("{}", Solution::cutting_rope(120)); +} + +struct Solution; + +impl Solution { + pub fn cutting_rope(n: i32) -> i32 { + if n <= 3 { + return n - 1; + } + + let (a, b) = (n / 3, n % 3); + + let r = match b { + 0 => Self::calc(a as u32, 1), + 1 => Self::calc(a as u32 - 1, 4), + 2 => Self::calc(a as u32, 2), + _ => unreachable!(), + }; + + (r % 1000000007) as i32 + } + + fn calc(x: u32, y: i64) -> i32 { + let mut r = 1i64; + for _i in 0..x { + r *= 3; + r %= 1000000007; + } + + (r * y % 1000000007) as i32 + } +} diff --git a/src/bin/jian-sheng-zi-lcof.rs b/src/bin/jian-sheng-zi-lcof.rs new file mode 100644 index 00000000..93fd5e22 --- /dev/null +++ b/src/bin/jian-sheng-zi-lcof.rs @@ -0,0 +1,37 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() { + assert_eq!(Solution::cutting_rope(10), 36); +} + +struct Solution; + +impl Solution { + /// 记住:剪成长度为3的最好 + pub fn cutting_rope1(n: i32) -> i32 { + if n <= 3 { + return n - 1; + } + + let (a, b) = (n / 3, n % 3); + match b { + 0 => 3i32.pow(a as u32), + 1 => 3i32.pow(a as u32 - 1) * 4, + 2 => 3i32.pow(a as u32) * 2, + _ => unreachable!(), + } + } + + pub fn cutting_rope(n: i32) -> i32 { + let mut dp = vec![0i32; n as usize + 1]; + dp[2] = 1; + + for i in 3..n + 1 { + for j in 2..i { + dp[i as usize] = dp[i as usize].max((j * (i - j)).max(j * dp[(i - j) as usize])); + } + } + + dp[n as usize] + } +} diff --git a/src/bin/ju-zhen-zhong-de-lu-jing-lcof.rs b/src/bin/ju-zhen-zhong-de-lu-jing-lcof.rs new file mode 100644 index 00000000..dd9d85b7 --- /dev/null +++ b/src/bin/ju-zhen-zhong-de-lu-jing-lcof.rs @@ -0,0 +1,78 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn exist(mut board: Vec>, word: String) -> bool { + let chars: Vec = word.chars().collect(); + for i in 0..board.len() { + for j in 0..board[i].len() { + if board[i][j] == chars[0] { + let x = board[i][j]; + board[i][j] = '0'; + if Self::scan(i, j, &mut board[..], &chars[1..]) { + return true; + } + + board[i][j] = x; + } + } + } + + false + } + + fn scan(i: usize, j: usize, board: &mut [Vec], word: &[char]) -> bool { + if word.is_empty() { + return true; + } + + if i > 0 { + if board[i - 1][j] == word[0] { + let x = board[i - 1][j]; + board[i - 1][j] = '0'; + if Self::scan(i - 1, j, board, &word[1..]) { + return true; + } + board[i - 1][j] = x; + } + } + + if j > 0 { + if board[i][j - 1] == word[0] { + let x = board[i][j - 1]; + board[i][j - 1] = '0'; + if Self::scan(i, j - 1, board, &word[1..]) { + return true; + } + board[i][j - 1] = x; + } + } + + if i < board.len() - 1 { + if board[i + 1][j] == word[0] { + let x = board[i + 1][j]; + board[i + 1][j] = '0'; + if Self::scan(i + 1, j, board, &word[1..]) { + return true; + } + board[i + 1][j] = x; + } + } + + if i <= board.len() - 1 && j < board[i].len() - 1 { + if board[i][j + 1] == word[0] { + let x = board[i][j + 1]; + board[i][j + 1] = '0'; + if Self::scan(i, j + 1, board, &word[1..]) { + return true; + } + board[i][j + 1] = x; + } + } + + false + } +} diff --git a/src/bin/jump-game-ii.rs b/src/bin/jump-game-ii.rs new file mode 100644 index 00000000..a1e072a5 --- /dev/null +++ b/src/bin/jump-game-ii.rs @@ -0,0 +1,78 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + println!("{}", Solution::jump(vec![2, 3, 1, 1, 4])); + println!("{}", Solution::jump(vec![1, 1, 1, 1])); + println!( + "{}", + Solution::jump(vec![ + 5, 6, 4, 4, 6, 9, 4, 4, 7, 4, 4, 8, 2, 6, 8, 1, 5, 9, 6, 5, 2, 7, 9, 7, 9, 6, 9, 4, 1, + 6, 8, 8, 4, 4, 2, 0, 3, 8, 5 + ]) + ); + println!( + "{}", + Solution::jump(vec![5, 9, 3, 2, 1, 0, 2, 3, 3, 1, 0, 0]) + ); +} + +struct Solution; + +impl Solution { + /// 常规解法,用hash表记录每个下标到终点的最小距离 + pub fn jump1(nums: Vec) -> i32 { + if nums.len() <= 1 { + return 0; + } + + // 保存下标到终点的最小值 + let mut hash = std::collections::HashMap::::with_capacity(nums.len()); + Self::step(nums.as_ref(), 0, &mut hash); + *hash.get(&0).unwrap() + } + + fn step(nums: &Vec, start: usize, hash: &mut std::collections::HashMap) { + if hash.get(&start).is_some() { + return; + } + + for i in 1..=nums[start] { + if start + i as usize == nums.len() - 1 { + hash.insert(start, 1); + return; + } + + if nums[start + i as usize] == 0 { + continue; + } + + Self::step(nums, start + i as usize, hash); + } + + let mut min = 0; + for i in 1..=nums[start] { + if let Some(x) = hash.get(&(start + i as usize)) { + if min == 0 || 1 + *x < min { + min = 1 + *x; + } + } + } + if min != 0 { + hash.insert(start, min); + } + } + + pub fn jump(nums: Vec) -> i32 { + let (mut end, mut max_position, mut steps) = (0, 0, 0); + + for i in 0..nums.len() - 1 { + max_position = max_position.max(nums[i] + i as i32); + if i == end { + end = max_position as usize; + steps += 1; + } + } + + steps + } +} diff --git a/src/bin/jump-game-iii.rs b/src/bin/jump-game-iii.rs new file mode 100644 index 00000000..0157ec0f --- /dev/null +++ b/src/bin/jump-game-iii.rs @@ -0,0 +1,57 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + assert_eq!(false, Solution::can_reach(vec![3, 0, 2, 1, 2], 2)); +} + +struct Solution; + +impl Solution { + pub fn can_reach(arr: Vec, start: i32) -> bool { + let mut v = vec![false; arr.len()]; + Self::scan(&arr, &mut v, start) + } + + fn scan(arr: &Vec, op: &mut Vec, start: i32) -> bool { + if arr[start as usize] == 0 { + return true; + } + + op[start as usize] = true; + if start >= arr[start as usize] && ((arr[start as usize] + start) as usize) < arr.len() { + if op[(start - arr[start as usize]) as usize] + && op[(arr[start as usize] + start) as usize] + { + return false; + } + } else if start >= arr[start as usize] + && ((arr[start as usize] + start) as usize) >= arr.len() + { + if op[(start - arr[start as usize]) as usize] { + return false; + } + } else if start < arr[start as usize] + && ((arr[start as usize] + start) as usize) < arr.len() + { + if op[(arr[start as usize] + start) as usize] { + return false; + } + } + + if start >= arr[start as usize] { + let r = Self::scan(arr, op, start - arr[start as usize]); + if r { + return true; + } + } + + if ((arr[start as usize] + start) as usize) < arr.len() { + let r = Self::scan(arr, op, arr[start as usize] + start); + if r { + return true; + } + } + + false + } +} diff --git a/src/bin/jump-game-vi.rs b/src/bin/jump-game-vi.rs new file mode 100644 index 00000000..23f4c98c --- /dev/null +++ b/src/bin/jump-game-vi.rs @@ -0,0 +1,40 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() { + assert_eq!(Solution::max_result(vec![1, -1, -2, 4, -7, 3], 2), 7); +} + +struct Solution; + +impl Solution { + /// 使用单调递减栈stack。栈维护单调nums单调递减的数据下标。 + /// 因为stack单调递减,因此遍历到nums[i]时,只要stack.pop()的下标满足跳k步到i,则i的最大值只为nums[i] + nums[stack.pop_front()], + /// 然后弹出stack后面比nums[i]小的元素,最后把i插入stack中即可。 + pub fn max_result(nums: Vec, k: i32) -> i32 { + use std::collections::VecDeque; + let mut stack = VecDeque::new(); + stack.push_back(0usize); + let mut nums = nums; + + for i in 1..nums.len() { + while let Some(x) = stack.pop_front() { + if x + k as usize >= i { + nums[i] += nums[x]; + stack.push_front(x); + break; + } + } + + while let Some(index) = stack.pop_back() { + if nums[index] > nums[i] { + stack.push_back(index); + break; + } + } + + stack.push_back(i); + } + + nums.pop().unwrap() + } +} diff --git a/src/bin/jump-game.rs b/src/bin/jump-game.rs new file mode 100644 index 00000000..f351350a --- /dev/null +++ b/src/bin/jump-game.rs @@ -0,0 +1,25 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + assert_eq!(true, Solution::can_jump(vec![2, 3, 1, 1, 4])); + assert_eq!(false, Solution::can_jump(vec![3, 2, 1, 0, 4])); + assert_eq!(true, Solution::can_jump(vec![0])); +} + +struct Solution; + +impl Solution { + pub fn can_jump(nums: Vec) -> bool { + let mut max_position = 0; + + for i in 0..nums.len() { + if i > max_position { + return false; + } + + max_position = max_position.max(i + nums[i] as usize); + } + + true + } +} diff --git a/src/bin/k-items-with-the-maximum-sum.rs b/src/bin/k-items-with-the-maximum-sum.rs new file mode 100644 index 00000000..ec68afb5 --- /dev/null +++ b/src/bin/k-items-with-the-maximum-sum.rs @@ -0,0 +1,32 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn k_items_with_maximum_sum( + num_ones: i32, + num_zeros: i32, + num_neg_ones: i32, + k: i32, + ) -> i32 { + let mut k = k; + let mut r = 0; + + if k > num_ones { + k -= num_ones; + r += num_ones; + } else { + return k; + } + + if k > num_zeros { + k -= num_zeros; + } else { + return r; + } + + r - k + } +} diff --git a/src/bin/kLl5u1.rs b/src/bin/kLl5u1.rs new file mode 100644 index 00000000..91118c74 --- /dev/null +++ b/src/bin/kLl5u1.rs @@ -0,0 +1,38 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + /// 简单方式:记录每个数的下标, + /// 如果当前数为current,然后通过查找target-current的下标,如果存在则说明就是这两个数 + pub fn two_sum1(numbers: Vec, target: i32) -> Vec { + let mut map = std::collections::HashMap::new(); + + for (i, v) in numbers.into_iter().enumerate() { + if let Some(&x) = map.get(&(target - v)) { + return vec![x, i as i32]; + } + + map.insert(v, i as i32); + } + + unreachable!() + } + + /// 双指针。 + /// 因为数是已排序的,则两个指针,一个从前往后,一个从后往前遍历即可 + pub fn two_sum(numbers: Vec, target: i32) -> Vec { + let (mut p1, mut p2) = (0, numbers.len() - 1); + while p1 < p2 { + match (numbers[p1] + numbers[p2]).cmp(&target) { + std::cmp::Ordering::Equal => return vec![p1 as i32, p2 as i32], + std::cmp::Ordering::Less => p1 += 1, + std::cmp::Ordering::Greater => p2 -= 1, + } + } + + unreachable!() + } +} diff --git a/src/bin/keyboard-row.rs b/src/bin/keyboard-row.rs new file mode 100644 index 00000000..6c2c3277 --- /dev/null +++ b/src/bin/keyboard-row.rs @@ -0,0 +1,68 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + assert_eq!( + vec!["Alaska".to_string(), "Dad".to_string()], + Solution::find_words(vec![ + "Hello".to_string(), + "Alaska".to_string(), + "Dad".to_string(), + "Peace".to_string() + ]) + ); +} + +struct Solution; + +impl Solution { + pub fn find_words(words: Vec) -> Vec { + let v = vec![(); 10]; + let m1: std::collections::HashMap<_, _> = "qwertyuiop" + .as_bytes() + .into_iter() + .map(|x| *x) + .zip(v.iter()) + .collect(); + let m2: std::collections::HashMap<_, _> = "asdfghjkl" + .as_bytes() + .into_iter() + .map(|x| *x) + .zip(v.iter()) + .collect(); + let m3: std::collections::HashMap<_, _> = "zxcvbnm" + .as_bytes() + .into_iter() + .map(|x| *x) + .zip(v.iter()) + .collect(); + + let mut result = vec![]; + + for i in words.iter() { + let mut s = i.as_bytes()[0]; + if s < 97 { + s += 32; + } + let m = if let Some(_) = m1.get(&s) { + &m1 + } else if let Some(_) = m2.get(&s) { + &m2 + } else { + &m3 + }; + let mut flag = true; + for j in i.as_bytes() { + if let (None, None) = (m.get(j), m.get(&(*j + 32))) { + flag = false; + break; + } + } + + if flag { + result.push(i.clone()) + } + } + + result + } +} diff --git a/src/bin/kth-largest-element-in-an-array.rs b/src/bin/kth-largest-element-in-an-array.rs new file mode 100644 index 00000000..3636ad72 --- /dev/null +++ b/src/bin/kth-largest-element-in-an-array.rs @@ -0,0 +1,44 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + Solution::find_kth_largest(vec![1], 1); +} + +struct Solution; + +impl Solution { + pub fn find_kth_largest(nums: Vec, k: i32) -> i32 { + let mut nums = nums; + Self::heapify(&mut nums); + + for i in 1..k as usize { + Self::heapify(&mut nums[i..]) + } + + nums[k as usize - 1] + } + + fn heapify(nums: &mut [i32]) { + let index = (nums.len() - 1) / 2; + + for i in (0..=index).rev() { + Self::down_heap(nums, i); + } + } + + fn down_heap(nums: &mut [i32], mut index: usize) { + while index * 2 + 1 < nums.len() { + let mut max = index * 2 + 1; + if index * 2 + 2 < nums.len() && nums[index * 2 + 1] < nums[index * 2 + 2] { + max = index * 2 + 2; + } + + if nums[max] > nums[index] { + nums.swap(max, index); + index = max; + } else { + break; + } + } + } +} diff --git a/src/bin/kth-largest-sum-in-a-binary-tree.rs b/src/bin/kth-largest-sum-in-a-binary-tree.rs new file mode 100644 index 00000000..f2b9e8f2 --- /dev/null +++ b/src/bin/kth-largest-sum-in-a-binary-tree.rs @@ -0,0 +1,63 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +use std::cell::RefCell; +use std::rc::Rc; + +fn main() {} + +struct Solution; + +// Definition for a binary tree node. +#[derive(Debug, PartialEq, Eq)] +pub struct TreeNode { + pub val: i32, + pub left: Option>>, + pub right: Option>>, +} + +impl TreeNode { + #[inline] + pub fn new(val: i32) -> Self { + TreeNode { + val, + left: None, + right: None, + } + } +} + +impl Solution { + pub fn kth_largest_level_sum(root: Option>>, k: i32) -> i64 { + if root.is_none() { + return -1; + } + + let mut results = vec![]; + let mut stack = vec![root]; + + while !stack.is_empty() { + let mut sum = 0; + let mut new_stack = vec![]; + while let Some(x) = stack.pop() { + let r = x.unwrap(); + sum += r.borrow().val as i64; + let left = r.borrow_mut().left.take(); + if left.is_some() { + new_stack.push(left); + } + + let right = r.borrow_mut().right.take(); + if right.is_some() { + new_stack.push(right); + } + } + + results.push(std::cmp::Reverse(sum)); + stack = new_stack; + } + + results.sort_unstable(); + + results.get(k as usize - 1).map(|x| x.0).unwrap_or(-1) + } +} diff --git a/src/bin/kth-smallest-element-in-a-bst.rs b/src/bin/kth-smallest-element-in-a-bst.rs new file mode 100644 index 00000000..8c4b0d3d --- /dev/null +++ b/src/bin/kth-smallest-element-in-a-bst.rs @@ -0,0 +1,57 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +// Definition for a binary tree node. +#[derive(Debug, PartialEq, Eq)] +pub struct TreeNode { + pub val: i32, + pub left: Option>>, + pub right: Option>>, +} + +impl TreeNode { + #[inline] + pub fn new(val: i32) -> Self { + TreeNode { + val, + left: None, + right: None, + } + } +} + +use std::cell::RefCell; +use std::rc::Rc; + +impl Solution { + pub fn kth_smallest(root: Option>>, k: i32) -> i32 { + let mut k = k; + Self::bst(root, &mut k).unwrap() + } + + fn bst(root: Option>>, k: &mut i32) -> Option { + if root.is_none() { + return None; + } + + let r1 = Self::bst(root.as_ref().unwrap().borrow_mut().left.take(), k); + if r1.is_some() { + return r1; + } + + *k -= 1; + if *k == 0 { + return Some(root.as_ref().unwrap().borrow().val); + } + + let r2 = Self::bst(root.as_ref().unwrap().borrow_mut().right.take(), k); + if r2.is_some() { + return r2; + } + + None + } +} diff --git a/src/bin/kth-smallest-element-in-a-sorted-matrix.rs b/src/bin/kth-smallest-element-in-a-sorted-matrix.rs new file mode 100644 index 00000000..d3b2cbe5 --- /dev/null +++ b/src/bin/kth-smallest-element-in-a-sorted-matrix.rs @@ -0,0 +1,40 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + /// 二分查找法? + pub fn kth_smallest(matrix: Vec>, k: i32) -> i32 { + let (mut left, mut right) = (matrix[0][0], matrix[matrix.len() - 1][matrix.len() - 1]); + + while left < right { + let mid = left + (right - left) / 2; + let num = Self::get_number(&matrix[..], mid); + if num >= k { + right = mid; + } else { + left = mid + 1; + } + } + left + } + + /// 求个数 + fn get_number(matrix: &[Vec], mid: i32) -> i32 { + let (mut i, mut j) = (matrix.len() as i32 - 1, 0i32); + let mut num = 0; + + while i >= 0 && j < matrix.len() as i32 { + if matrix[i as usize][j as usize] <= mid { + num += i as i32 + 1; + j += 1; + } else { + i -= 1; + } + } + + num + } +} diff --git a/src/bin/kth-smallest-instructions.rs b/src/bin/kth-smallest-instructions.rs new file mode 100644 index 00000000..1c65397b --- /dev/null +++ b/src/bin/kth-smallest-instructions.rs @@ -0,0 +1,22 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +use std::vec; + +use serde::__private::de; + +fn main() {} + +struct Solution; + +impl Solution { + pub fn kth_smallest_path(destination: Vec, mut k: i32) -> String { + let mut max: Vec = (0..destination[1]) + .map(|_| b'H') + .chain((0..destination[0]).map(|_| b'V')) + .collect(); + + while k > 0 {} + + unsafe { String::from_utf8_unchecked(max) } + } +} diff --git a/src/bin/lMSNwu.rs b/src/bin/lMSNwu.rs new file mode 100644 index 00000000..68b873a7 --- /dev/null +++ b/src/bin/lMSNwu.rs @@ -0,0 +1,97 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +// Definition for singly-linked list. +#[derive(PartialEq, Eq, Clone, Debug)] +pub struct ListNode { + pub val: i32, + pub next: Option>, +} + +impl ListNode { + #[inline] + fn new(val: i32) -> Self { + ListNode { next: None, val } + } +} + +impl Solution { + pub fn add_two_numbers( + l1: Option>, + l2: Option>, + ) -> Option> { + let mut a = vec![]; + let mut current = l1.as_deref(); + while current.is_some() { + let c = current.unwrap(); + a.push(c.val); + current = c.next.as_deref(); + } + + let mut b = vec![]; + let mut current = l2.as_deref(); + while current.is_some() { + let c = current.unwrap(); + b.push(c.val); + current = c.next.as_deref(); + } + + let mut dummy = Some(Box::new(ListNode::new(-1))); + let mut f = 0; + loop { + let val = match (a.pop(), b.pop()) { + (Some(x), Some(y)) => { + let mut v = x + y + f; + f = 0; + if v > 9 { + f = v / 10; + v = v % 10; + } + + v + } + + (Some(x), None) => { + let mut v = x + f; + f = 0; + if v > 9 { + f = v / 10; + v = v % 10; + } + + v + } + + (None, Some(y)) => { + let mut v = y + f; + f = 0; + if v > 9 { + f = v / 10; + v = v % 10; + } + + v + } + + (None, None) => break, + }; + + let n = dummy.as_deref_mut().and_then(|x| x.next.take()); + let mut c = Box::new(ListNode { val, next: n }); + + dummy.as_deref_mut().unwrap().next.insert(c); + } + + if f != 0 { + let n = dummy.as_deref_mut().and_then(|x| x.next.take()); + let mut c = Box::new(ListNode { val: f, next: n }); + + dummy.as_deref_mut().unwrap().next.insert(c); + } + + dummy.unwrap().next + } +} diff --git a/src/bin/largest-3-same-digit-number-in-string.rs b/src/bin/largest-3-same-digit-number-in-string.rs new file mode 100644 index 00000000..736c4b5e --- /dev/null +++ b/src/bin/largest-3-same-digit-number-in-string.rs @@ -0,0 +1,30 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn largest_good_integer(num: String) -> String { + let mut current = b' '; + let mut count = 0; + let mut result = String::new(); + for i in 0..num.len() { + if num.as_bytes()[i] == current { + count += 1; + if count == 3 { + if result < num[i - 2..=i].to_owned() { + result = num[i - 2..=i].to_owned(); + } + current = b' '; + count = 0; + } + } else { + current = num.as_bytes()[i]; + count = 1; + } + } + + result + } +} diff --git a/src/bin/largest-element-in-an-array-after-merge-operations.rs b/src/bin/largest-element-in-an-array-after-merge-operations.rs new file mode 100644 index 00000000..6de33364 --- /dev/null +++ b/src/bin/largest-element-in-an-array-after-merge-operations.rs @@ -0,0 +1,21 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn max_array_value(nums: Vec) -> i64 { + let mut result = nums[nums.len() - 1] as i64; + + for i in (0..nums.len() - 1).rev() { + result = if nums[i] as i64 <= result { + result + nums[i] as i64 + } else { + nums[i] as i64 + }; + } + + result + } +} diff --git a/src/bin/largest-odd-number-in-string.rs b/src/bin/largest-odd-number-in-string.rs new file mode 100644 index 00000000..da4a264a --- /dev/null +++ b/src/bin/largest-odd-number-in-string.rs @@ -0,0 +1,19 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn largest_odd_number(num: String) -> String { + let mut s = num.as_bytes(); + + for i in (0..s.len()).rev() { + if (s[i] - b'0') % 2 == 1 { + return String::from_utf8(s[..=i].to_vec()).unwrap(); + } + } + + "".into() + } +} diff --git a/src/bin/largest-rectangle-in-histogram.rs b/src/bin/largest-rectangle-in-histogram.rs new file mode 100644 index 00000000..a40f7ea0 --- /dev/null +++ b/src/bin/largest-rectangle-in-histogram.rs @@ -0,0 +1,95 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() { + assert_eq!( + Solution::force_largest_rectangle_area(vec![2, 1, 5, 6, 2, 3]), + 10 + ); + assert_eq!(Solution::force_largest_rectangle_area(vec![2, 4]), 4); + assert_eq!(Solution::force_largest_rectangle_area(vec![1, 1]), 2); + assert_eq!(Solution::force_largest_rectangle_area(vec![2, 1, 2]), 3); + assert_eq!(Solution::force_largest_rectangle_area(vec![5, 4, 1, 2]), 8); + + assert_eq!(Solution::largest_rectangle_area(vec![2, 1, 5, 6, 2, 3]), 10); + assert_eq!(Solution::largest_rectangle_area(vec![2, 4]), 4); + assert_eq!(Solution::largest_rectangle_area(vec![1, 1]), 2); + assert_eq!(Solution::largest_rectangle_area(vec![2, 1, 2]), 3); + assert_eq!(Solution::largest_rectangle_area(vec![5, 4, 1, 2]), 8); + assert_eq!(Solution::largest_rectangle_area(vec![4, 2, 0, 3, 2, 5]), 6); + assert_eq!( + Solution::largest_rectangle_area(vec![3, 6, 5, 7, 4, 8, 1, 0]), + 20 + ); +} + +struct Solution; + +impl Solution { + /// 暴力解法 + pub fn force_largest_rectangle_area(heights: Vec) -> i32 { + let mut ans = 0; + + for i in 0..heights.len() { + let mut left = i; + + for j in (0..i).rev() { + if heights[j] >= heights[i] { + left = j; + } else { + break; + } + } + + let mut right = i; + + for j in i..heights.len() { + if heights[j] >= heights[i] { + right = j; + } else { + break; + } + } + + ans = ans.max((right - left + 1) as i32 * heights[i]) + } + + ans + } + + pub fn largest_rectangle_area(heights: Vec) -> i32 { + let len = heights.len(); + if len == 1 { + return heights[0]; + } + + let mut stack: Vec = vec![]; + let mut ans = 0; + + // 循环便利整个heights + for i in 0..len { + while !stack.is_empty() && heights[stack[stack.len() - 1]] > heights[i] { + let h = stack.pop().unwrap(); + if !stack.is_empty() { + ans = ans.max(heights[h] * (i - *stack.last().unwrap_or(&0) - 1) as i32); + } else { + ans = ans.max(heights[h] * (i - *stack.last().unwrap_or(&0)) as i32); + } + } + + stack.push(i); + } + + let last = *stack.last().unwrap_or(&0); + + while !stack.is_empty() { + let h = stack.pop().unwrap(); + if stack.is_empty() { + ans = ans.max(heights[h] * len as i32); + } else { + ans = ans.max(heights[h] * (last - *stack.last().unwrap_or(&0)) as i32); + } + } + + ans + } +} diff --git a/src/bin/latest-time-by-replacing-hidden-digits.rs b/src/bin/latest-time-by-replacing-hidden-digits.rs new file mode 100644 index 00000000..06ee03b8 --- /dev/null +++ b/src/bin/latest-time-by-replacing-hidden-digits.rs @@ -0,0 +1,42 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn maximum_time(mut time: String) -> String { + let mut f = false; + unsafe { + let mut s = time.as_bytes_mut(); + for i in 0..s.len() { + if s[i] == b'?' { + match i { + 0 => { + if s[1] == b'?' || (s[1] >= b'0' && s[1] <= b'3') { + s[0] = b'2'; + } else { + s[0] = b'1'; + } + } + 1 => { + if f { + s[1] = b'3'; + } else { + s[1] = b'9'; + } + } + + 3 => s[3] = b'5', + 4 => s[4] = b'9', + _ => {} + } + } + + f = s[0] == b'2'; + } + } + + time + } +} diff --git a/src/bin/leaf-similar-trees.rs b/src/bin/leaf-similar-trees.rs new file mode 100644 index 00000000..099e7649 --- /dev/null +++ b/src/bin/leaf-similar-trees.rs @@ -0,0 +1,57 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +use std::cell::RefCell; +use std::rc::Rc; + +fn main() {} + +struct Solution; + +// Definition for a binary tree node. +#[derive(Debug, PartialEq, Eq)] +pub struct TreeNode { + pub val: i32, + pub left: Option>>, + pub right: Option>>, +} + +impl TreeNode { + #[inline] + pub fn new(val: i32) -> Self { + TreeNode { + val, + left: None, + right: None, + } + } +} + +impl Solution { + pub fn leaf_similar( + root1: Option>>, + root2: Option>>, + ) -> bool { + let mut v1 = vec![]; + let mut v2 = vec![]; + Self::get(root1, &mut v1); + Self::get(root2, &mut v2); + + v1 == v2 + } + + fn get(root: Option>>, v: &mut Vec) { + if root.is_none() { + return; + } + + let root = root.unwrap(); + let left = root.borrow_mut().left.take(); + let right = root.borrow_mut().right.take(); + if left.is_none() && right.is_none() { + v.push(root.borrow().val); + } + + Self::get(left, v); + Self::get(right, v); + } +} diff --git a/src/bin/least-number-of-unique-integers-after-k-removals.rs b/src/bin/least-number-of-unique-integers-after-k-removals.rs new file mode 100644 index 00000000..e18401a7 --- /dev/null +++ b/src/bin/least-number-of-unique-integers-after-k-removals.rs @@ -0,0 +1,35 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn find_least_num_of_unique_ints(arr: Vec, k: i32) -> i32 { + let mut h = std::collections::HashMap::new(); + + for i in arr { + h.entry(i).and_modify(|x| *x += 1).or_insert(1); + } + + let mut s = h.iter().map(|(_x, y)| *y).collect::>(); + s.sort(); + + let (mut l, mut k) = (h.len(), k); + + for i in s { + if k == 0 { + break; + } + + if i <= k { + k -= i; + l -= 1; + } else { + k -= k; + } + } + + l as i32 + } +} diff --git a/src/bin/lemonade-change.rs b/src/bin/lemonade-change.rs new file mode 100644 index 00000000..9c9233ef --- /dev/null +++ b/src/bin/lemonade-change.rs @@ -0,0 +1,41 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn lemonade_change(bills: Vec) -> bool { + let mut moneys = [0; 2]; // 第一个元素代表5的个数,第二个代表10的个数 + + for i in bills { + match i { + 5 => moneys[0] += 1, + 10 => { + if moneys[0] == 0 { + return false; + } + + moneys[0] -= 1; + moneys[1] += 1; + } + 20 => { + // 可以找1张5元+1张10元 + // 也可以找3张5元 + // 优先找10元 + if moneys[0] >= 1 && moneys[1] >= 1 { + moneys[0] -= 1; + moneys[1] -= 1; + } else if moneys[0] >= 3 { + moneys[0] -= 3; + } else { + return false; + } + } + _ => unreachable!(), + } + } + + true + } +} diff --git a/src/bin/length-of-last-word.rs b/src/bin/length-of-last-word.rs new file mode 100644 index 00000000..6e2fe888 --- /dev/null +++ b/src/bin/length-of-last-word.rs @@ -0,0 +1,23 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn length_of_last_word(s: String) -> i32 { + let mut count = 0; + let s = s.as_bytes(); + for v in (0..s.len()).rev() { + if s[v] != b' ' { + count += 1; + } + + if count != 0 && s[v] == b' ' { + break; + } + } + + count + } +} diff --git a/src/bin/length-of-longest-fibonacci-subsequence.rs b/src/bin/length-of-longest-fibonacci-subsequence.rs new file mode 100644 index 00000000..06a75742 --- /dev/null +++ b/src/bin/length-of-longest-fibonacci-subsequence.rs @@ -0,0 +1,76 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() { + assert_eq!( + Solution::len_longest_fib_subseq(vec![1, 2, 3, 4, 5, 6, 7, 8]), + 5 + ); + assert_eq!( + Solution::len_longest_fib_subseq(vec![1, 3, 7, 11, 12, 14, 18]), + 3 + ); +} + +struct Solution; + +impl Solution { + /// 暴力搜索, 双指针 + /// p1 = arr[0], p2 = arr[1], 如果 p1+p2在arr存在,则 p1, p2 = p2, p1+p2,结果+1;如果不存在,则推出循环 + pub fn force_len_longest_fib_subseq(arr: Vec) -> i32 { + let mut set = arr + .iter() + .map(|x| *x) + .collect::>(); + let mut ans = 0; + + for i in 0..arr.len() - 2 { + let mut _ans = -1; + for j in i + 1..arr.len() - 1 { + let mut current1 = arr[i]; + let mut current2 = arr[j]; + + while set.contains(&(current1 + current2)) { + _ans = (_ans + 1).max(3); + let _current1 = current2; + current2 = current1 + current2; + current1 = _current1; + } + + ans = ans.max(_ans); + _ans = -1; + } + } + + ans + } + + /// dp + /// dp[i][j]表示以arr[i]和arr[j]开始的最大值 + /// 则 dp[i][j] = 1 + dp[j][arr[i] +arr[j]] if arr[i] + arr[j] 存在的话 + pub fn len_longest_fib_subseq(arr: Vec) -> i32 { + let mut map = arr + .iter() + .enumerate() + .map(|(x, y)| (*y, x)) + .collect::>(); + let mut ans = 0; + + let mut dp = vec![vec![-1; arr.len()]; arr.len()]; + + for i in (0..arr.len() - 2).rev() { + for j in (i + 1..arr.len() - 1) { + let mut inner = 0; + let mut sum = arr[i] + arr[j]; + match map.get(&sum) { + Some(&x) => inner = (dp[j][x] + 1).max(3), + None => inner = 0, + } + + dp[i][j] = inner; + ans = ans.max(inner); + } + } + + ans + } +} diff --git a/src/bin/letter-case-permutation.rs b/src/bin/letter-case-permutation.rs new file mode 100644 index 00000000..66f0b723 --- /dev/null +++ b/src/bin/letter-case-permutation.rs @@ -0,0 +1,43 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn letter_case_permutation(s: String) -> Vec { + let mut v = Vec::new(); + Self::func(s, &mut v, 0); + v + } + + fn func(s: String, v: &mut Vec, index: usize) { + let mut new_s = s.clone(); + let new_s = unsafe { new_s.as_bytes_mut() }; + v.push(s); + if index == new_s.len() { + return; + } + let mut new_index = index; + for i in index..new_s.len() { + new_index = i; + if new_s[i] >= b'a' && new_s[i] <= b'z' { + new_s[i] -= 32; + Self::func( + unsafe { String::from_utf8_unchecked(new_s.to_vec()) }, + v, + new_index + 1, + ); + new_s[i] += 32; + } else if new_s[i] >= b'A' && new_s[i] <= b'Z' { + new_s[i] += 32; + Self::func( + unsafe { String::from_utf8_unchecked(new_s.to_vec()) }, + v, + new_index + 1, + ); + new_s[i] -= 32; + } + } + } +} diff --git a/src/bin/letter-combinations-of-a-phone-number.rs b/src/bin/letter-combinations-of-a-phone-number.rs new file mode 100644 index 00000000..0bfc33b1 --- /dev/null +++ b/src/bin/letter-combinations-of-a-phone-number.rs @@ -0,0 +1,45 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +static V: &[&str; 10] = &[ + "", "!@#", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz", +]; + +impl Solution { + pub fn letter_combinations(digits: String) -> Vec { + if digits.len() == 0 { + return vec![]; + } + + Self::scan(digits.as_bytes()) + } + + fn scan(s: &[u8]) -> Vec { + if s.len() == 1 { + let mut v = vec![]; + + for i in V[(s[0] - b'0') as usize].chars() { + v.push(i.to_string()); + } + return v; + } + + let mut v1 = vec![]; + + let s1 = Self::scan(&s[1..]); + + for i in V[(s[0] - b'0') as usize].chars() { + for j in s1.iter() { + let mut s2 = String::new(); + s2.push(i); + s2.push_str(j.as_str()); + v1.push(s2); + } + } + + v1 + } +} diff --git a/src/bin/lexicographical-numbers.rs b/src/bin/lexicographical-numbers.rs new file mode 100644 index 00000000..c8b92e61 --- /dev/null +++ b/src/bin/lexicographical-numbers.rs @@ -0,0 +1,45 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn lexical_order1(n: i32) -> Vec { + let mut s = (1..=n) + .into_iter() + .map(|x| x.to_string()) + .collect::>(); + + s.sort(); + + s.into_iter() + .map(|x| x.parse::().unwrap()) + .collect::>() + } + + pub fn lexical_order(n: i32) -> Vec { + let mut v = Vec::with_capacity(n as usize); + + for i in 1..10.min(n + 1) { + v.push(i); + Self::dfs(&mut v, i, n); + } + v + } + + fn dfs(v: &mut Vec, number: i32, n: i32) { + if number > n { + return; + } + + let number = number * 10; + + for i in 0..10 { + if number + i <= n { + v.push(number + i); + Self::dfs(v, number + i, n); + } + } + } +} diff --git a/src/bin/lexicographically-smallest-palindrome.rs b/src/bin/lexicographically-smallest-palindrome.rs new file mode 100644 index 00000000..cae684bb --- /dev/null +++ b/src/bin/lexicographically-smallest-palindrome.rs @@ -0,0 +1,25 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn make_smallest_palindrome(s: String) -> String { + let mut s = s.into_bytes(); + let (mut i, mut j) = (0, s.len() - 1); + + while i < j { + if s[i] > s[j] { + s[i] = s[j]; + } else if s[i] < s[j] { + s[j] = s[i]; + } + + i += 1; + j -= 1; + } + + unsafe { String::from_utf8_unchecked(s) } + } +} diff --git a/src/bin/lexicographically-smallest-string-after-operations-with-constraint.rs b/src/bin/lexicographically-smallest-string-after-operations-with-constraint.rs new file mode 100644 index 00000000..41e0e5c9 --- /dev/null +++ b/src/bin/lexicographically-smallest-string-after-operations-with-constraint.rs @@ -0,0 +1,27 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn get_smallest_string(s: String, k: i32) -> String { + let mut r = 0; + let mut k = k; + let mut result = Vec::with_capacity(s.len()); + + for i in s.bytes() { + if k >= (i - b'a').min(b'z' + 1 - i) as i32 { + result.push(b'a'); + k -= (i - b'a').min(b'z' + 1 - i) as i32; + } else if k > 0 { + result.push(i - k as u8); + k = 0; + } else { + result.push(i); + } + } + + String::from_utf8(result).unwrap() + } +} diff --git a/src/bin/lexicographically-smallest-string-after-substring-operation.rs b/src/bin/lexicographically-smallest-string-after-substring-operation.rs new file mode 100644 index 00000000..fd03bab2 --- /dev/null +++ b/src/bin/lexicographically-smallest-string-after-substring-operation.rs @@ -0,0 +1,32 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn smallest_string(s: String) -> String { + let s = s.as_bytes(); + let mut s1 = vec![]; + let mut flag = false; + for i in 0..s.len() { + if s[i] == b'a' && i != s.len() - 1 { + if flag { + s1.extend_from_slice(&s[i..]); + break; + } else { + s1.push(b'a'); + } + } else { + flag = true; + if s[i] != b'a' { + s1.push(s[i] - 1); + } else { + s1.push(b'a'); + } + } + } + + unsafe { String::from_utf8_unchecked(s1) } + } +} diff --git a/src/bin/lfu-cache.rs b/src/bin/lfu-cache.rs new file mode 100644 index 00000000..00939d11 --- /dev/null +++ b/src/bin/lfu-cache.rs @@ -0,0 +1,230 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +struct LinkList { + head: Option>>, + tail: Option>>, +} + +struct Node { + next: Option>>, + prev: Option>>, + key: i32, + val: i32, +} + +impl LinkList { + fn new() -> Self { + Self { + head: None, + tail: None, + } + } + + fn push_front(&mut self, key: i32, val: i32) -> std::rc::Rc> { + use std::cell::RefCell; + use std::rc::Rc; + + let node = Rc::new(RefCell::new(Node { + prev: None, + next: None, + key, + val, + })); + + if self.head.is_none() { + self.head = Some(Rc::clone(&node)); + self.tail = Some(Rc::clone(&node)); + } else { + let mut head = self.head.take(); + head.as_ref() + .map(|x| x.borrow_mut().prev = Some(Rc::downgrade(&node))); + node.borrow_mut().next = head.clone(); + self.head = Some(Rc::clone(&node)); + } + + node + } + + fn remove(&mut self, val: std::rc::Rc>) { + use std::cell::RefCell; + use std::rc::Rc; + + let prev = val.borrow_mut().prev.take().and_then(|x| x.upgrade()); + let next = val.borrow_mut().next.take(); + + prev.as_ref().map(|x| x.borrow_mut().next = None); + next.as_ref().map(|x| x.borrow_mut().prev = None); + + prev.as_ref().map(|x| x.borrow_mut().next = next.clone()); + next.as_ref() + .map(|x| x.borrow_mut().prev = prev.clone().map(|x| Rc::downgrade(&x))); + + // 移除节点的前继节点为空,说明此节点为头节点,移除next节点成为新的头部节点 + if prev.is_none() { + self.head = next.clone(); + } + + if next.is_none() { + self.tail = prev.clone(); + } + } + + fn is_empty(&self) -> bool { + self.head.is_none() + } + + fn pop(&mut self) -> Option { + let tail = self.tail.clone(); + if tail.is_none() { + return None; + } + self.remove(tail.clone().unwrap()); + tail.clone().map(|x| x.borrow().key) + } +} + +struct LFUCache { + /// 容量 + capacity: usize, + length: usize, + /// 存放数据的集合, 题目不需要delete,data:(frequency, Node) + data: std::collections::HashMap>)>, + /// 存放节点的频率 + frequencies: std::collections::HashMap, + /// 当前最小的频率 + min_frequency: i32, +} + +/** + * `&self` means the method takes an immutable reference. + * If you need a mutable reference, change it to `&mut self` instead. + */ + +/** + * Your LFUCache object will be instantiated and called as such: + * let obj = LFUCache::new(capacity); + * let ret_1: i32 = obj.get(key); + * obj.put(key, value); + */ +impl LFUCache { + fn new(capacity: i32) -> Self { + use std::collections::HashMap; + Self { + capacity: capacity as _, + length: 0, + data: HashMap::new(), + frequencies: HashMap::new(), + min_frequency: 0, + } + } + + fn get(&mut self, key: i32) -> i32 { + if !self.data.contains_key(&key) { + return -1; + } + + self.increment(key, None) + } + + fn put(&mut self, key: i32, value: i32) { + if self.data.contains_key(&key) { + self.increment(key, Some(value)); + } else { + // 如果长度==容量,先要移除最小频率的值 + if self.length == self.capacity { + let k = self + .frequencies + .get_mut(&self.min_frequency) + .and_then(|x| x.pop()); + + k.map(|x| self.data.remove(&x)); + self.length -= 1; + + if self + .frequencies + .get(&self.min_frequency) + .map(|x| x.is_empty()) + .unwrap_or(true) + { + self.frequencies.remove(&self.min_frequency); + } + {} + } + self.length += 1; + self.min_frequency = 1; + + if self.frequencies.get(&1).is_none() { + let mut l = LinkList::new(); + self.data.insert(key, (1, l.push_front(key, value))); + self.frequencies.insert(1, l); + return; + } + + let a = if let Some(x) = self.frequencies.get_mut(&1) { + x.push_front(key, value) + } else { + return; + }; + self.data.insert(key, (1, a)); + } + } + + /// 增加key的频率,当new_val为Some时,替换key的值,返回旧值 + fn increment(&mut self, key: i32, new_val: Option) -> i32 { + let r = self.data.get(&key).unwrap(); + if let Some(val) = new_val { + r.1.borrow_mut().val = val; + } + + let val = r.1.borrow().val; + let fre = r.0; + + self.frequencies + .get_mut(&fre) + .map(|x| x.remove(r.1.clone())); + + if self.frequencies[&fre].is_empty() { + self.frequencies.remove(&fre); + + if fre == self.min_frequency { + self.min_frequency = fre + 1; + } + } + + if self.frequencies.get(&(fre + 1)).is_none() { + let mut l = LinkList::new(); + self.data.insert(key, (fre + 1, l.push_front(key, val))); + self.frequencies.insert(fre + 1, l); + return val; + } + + let a = if let Some(x) = self.frequencies.get_mut(&(fre + 1)) { + x.push_front(key, val) + } else { + return val; + }; + self.data.insert(key, (fre + 1, a)); + val + } +} + +impl std::fmt::Debug for LFUCache { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_map() + .entries(self.data.iter().map(|x| (*x.0, x.1 .0))) + .finish()?; + + f.debug_list() + .entries(self.frequencies.iter().map(|x| *x.0)) + .finish()?; + + f.debug_map() + .key(&"min") + .value(&self.min_frequency) + .finish() + } +} diff --git a/src/bin/li-wu-de-zui-da-jie-zhi-lcof.rs b/src/bin/li-wu-de-zui-da-jie-zhi-lcof.rs new file mode 100644 index 00000000..5e58385b --- /dev/null +++ b/src/bin/li-wu-de-zui-da-jie-zhi-lcof.rs @@ -0,0 +1,37 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn max_value(grid: Vec>) -> i32 { + let mut dp = vec![vec![0; grid[0].len()]; grid.len()]; + Self::dp(&grid, &mut dp, (0, 0)); + + dp[0][0] + } + + fn dp(grid: &[Vec], dp: &mut [Vec], index: (usize, usize)) { + if index.0 == grid.len() - 1 && index.1 == grid[0].len() - 1 { + dp[index.0][index.1] = grid[index.0][index.1]; + } + + if index.0 + 1 < grid.len() && dp[index.0 + 1][index.1] == 0 { + Self::dp(grid, dp, (index.0 + 1, index.1)); + } + + if index.1 + 1 < grid[0].len() && dp[index.0][index.1 + 1] == 0 { + Self::dp(grid, dp, (index.0, index.1 + 1)); + } + + if index.0 + 1 < grid.len() && index.1 + 1 < grid[0].len() { + dp[index.0][index.1] = + grid[index.0][index.1] + dp[index.0 + 1][index.1].max(dp[index.0][index.1 + 1]); + } else if index.0 + 1 < grid.len() { + dp[index.0][index.1] = grid[index.0][index.1] + dp[index.0 + 1][index.1]; + } else if index.1 + 1 < grid[0].len() { + dp[index.0][index.1] = grid[index.0][index.1] + dp[index.0][index.1 + 1]; + } + } +} diff --git a/src/bin/lian-biao-zhong-dao-shu-di-kge-jie-dian-lcof.rs b/src/bin/lian-biao-zhong-dao-shu-di-kge-jie-dian-lcof.rs new file mode 100644 index 00000000..536a9fbe --- /dev/null +++ b/src/bin/lian-biao-zhong-dao-shu-di-kge-jie-dian-lcof.rs @@ -0,0 +1,37 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +// Definition for singly-linked list. +#[derive(PartialEq, Eq, Clone, Debug)] +pub struct ListNode { + pub val: i32, + pub next: Option>, +} + +impl ListNode { + #[inline] + fn new(val: i32) -> Self { + ListNode { next: None, val } + } +} +impl Solution { + pub fn get_kth_from_end(mut head: Option>, k: i32) -> Option> { + let mut h = head.as_ref(); + let mut len = 0; + + while h.is_some() { + len += 1; + h = h.unwrap().next.as_ref(); + } + + while len > k { + head = head.unwrap().next.take(); + len -= 1; + } + + head + } +} diff --git a/src/bin/lian-xu-zi-shu-zu-de-zui-da-he-lcof.rs b/src/bin/lian-xu-zi-shu-zu-de-zui-da-he-lcof.rs new file mode 100644 index 00000000..498ceb8b --- /dev/null +++ b/src/bin/lian-xu-zi-shu-zu-de-zui-da-he-lcof.rs @@ -0,0 +1,53 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +use std::vec; + +fn main() { + assert_eq!( + Solution::max_sub_array(vec![-2, 1, -3, 4, -1, 2, 1, -5, 4]), + 6 + ); +} + +struct Solution; + +impl Solution { + pub fn max_sub_array1(nums: Vec) -> i32 { + let mut dp = vec![0; nums.len()]; + dp[0] = nums[0]; + let mut result = dp[0]; + + for i in 1..nums.len() { + if dp[i - 1] > 0 { + dp[i] = dp[i - 1] + nums[i]; + } else { + dp[i] = nums[i]; + } + + if dp[i] > result { + result = dp[i]; + } + } + + result + } + + pub fn max_sub_array(nums: Vec) -> i32 { + let mut dp = nums[0]; + let mut result = dp; + + for &i in nums[1..].iter() { + if dp > 0 { + dp += i; + } else { + dp = i; + } + + if dp > result { + result = dp; + } + } + + result + } +} diff --git a/src/bin/linked-list-components.rs b/src/bin/linked-list-components.rs new file mode 100644 index 00000000..c254da68 --- /dev/null +++ b/src/bin/linked-list-components.rs @@ -0,0 +1,43 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +// Definition for singly-linked list. +#[derive(PartialEq, Eq, Clone, Debug)] +pub struct ListNode { + pub val: i32, + pub next: Option>, +} + +impl ListNode { + #[inline] + fn new(val: i32) -> Self { + ListNode { next: None, val } + } +} + +impl Solution { + pub fn num_components(head: Option>, nums: Vec) -> i32 { + let set = nums.into_iter().collect::>(); + let mut head = head; + let mut result = 0; + let mut flag = false; + while head.is_some() { + let v = head.as_ref().unwrap().val; + if set.contains(&v) { + if !flag { + result += 1; + flag = true; + } + } else { + flag = false; + } + + head = head.as_mut().unwrap().next.take(); + } + + result + } +} diff --git a/src/bin/linked-list-in-binary-tree.rs b/src/bin/linked-list-in-binary-tree.rs new file mode 100644 index 00000000..e859a0ad --- /dev/null +++ b/src/bin/linked-list-in-binary-tree.rs @@ -0,0 +1,74 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +use std::cell::RefCell; +use std::rc::Rc; + +fn main() {} + +struct Solution; + +// Definition for singly-linked list. +#[derive(PartialEq, Eq, Clone, Debug)] +pub struct ListNode { + pub val: i32, + pub next: Option>, +} + +impl ListNode { + #[inline] + fn new(val: i32) -> Self { + ListNode { next: None, val } + } +} + +// Definition for a binary tree node. +#[derive(Debug, PartialEq, Eq)] +pub struct TreeNode { + pub val: i32, + pub left: Option>>, + pub right: Option>>, +} + +impl TreeNode { + #[inline] + pub fn new(val: i32) -> Self { + TreeNode { + val, + left: None, + right: None, + } + } +} + +impl Solution { + pub fn is_sub_path(head: Option>, root: Option>>) -> bool { + if root.is_none() { + return false; + } + + Self::dfs(head.clone(), root.clone()) + || Self::is_sub_path( + head.clone(), + root.clone().and_then(|x| x.borrow().left.clone()), + ) + || Self::is_sub_path( + head.clone(), + root.clone().and_then(|x| x.borrow().right.clone()), + ) + } + + fn dfs(head: Option>, root: Option>>) -> bool { + match (head.clone(), root.clone()) { + (Some(h), Some(r)) => { + if h.val != r.borrow().val { + return false; + } + + Self::dfs(h.next.clone(), r.borrow().left.clone()) + || Self::dfs(h.next.clone(), r.borrow().right.clone()) + } + (Some(h), None) => false, + _ => true, + } + } +} diff --git a/src/bin/linked-list-random-node.rs b/src/bin/linked-list-random-node.rs new file mode 100644 index 00000000..1ac2aff1 --- /dev/null +++ b/src/bin/linked-list-random-node.rs @@ -0,0 +1,57 @@ +#![allow(dead_code, unused, unused_variables)] + +use rand::Rng; + +fn main() {} + +// Definition for singly-linked list. +#[derive(PartialEq, Eq, Clone, Debug)] +pub struct ListNode { + pub val: i32, + pub next: Option>, +} + +impl ListNode { + #[inline] + fn new(val: i32) -> Self { + ListNode { next: None, val } + } +} + +/** + * Your Solution object will be instantiated and called as such: + * let obj = Solution::new(head); + * let ret_1: i32 = obj.get_random(); + */ +struct Solution { + head: Option>, +} + +/** + * `&self` means the method takes an immutable reference. + * If you need a mutable reference, change it to `&mut self` instead. + */ +impl Solution { + /** @param head The linked list's head. + Note that the head is guaranteed to be not null, so it contains at least one node. */ + fn new(head: Option>) -> Self { + Self { head } + } + + /** Returns a random node's value. */ + fn get_random(&self) -> i32 { + use rand::Rng; + let mut s = &self.head; + let mut n = 1; + let mut r = 0; + while let Some(x) = s { + if rand::thread_rng().gen_range(0..n) == 0 { + r = x.val; + } + + s = &x.next; + n += 1; + } + r + } +} diff --git a/src/bin/living-people-lcci.rs b/src/bin/living-people-lcci.rs new file mode 100644 index 00000000..aedc89c3 --- /dev/null +++ b/src/bin/living-people-lcci.rs @@ -0,0 +1,35 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +use std::cmp::max; + +fn main() {} + +struct Solution; + +impl Solution { + pub fn max_alive_year(birth: Vec, death: Vec) -> i32 { + let mut s = std::collections::HashMap::new(); + let mut max_year = i32::MAX; + let mut max_num = 0; + for i in 0..birth.len() { + for j in birth[i]..=death[i] { + s.entry(j).and_modify(|x| *x += 1).or_insert(1); + if s[&j] > max_num { + max_num = s[&j]; + max_year = j; + } + + match s[&j].cmp(&max_num) { + std::cmp::Ordering::Equal => max_year = max_year.min(j), + std::cmp::Ordering::Greater => { + max_year = j; + max_num = s[&j]; + } + _ => {} + } + } + } + + max_year + } +} diff --git a/src/bin/longest-alternating-subarray.rs b/src/bin/longest-alternating-subarray.rs new file mode 100644 index 00000000..eb92e7cd --- /dev/null +++ b/src/bin/longest-alternating-subarray.rs @@ -0,0 +1,37 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() { + assert_eq!(Solution::alternating_subarray(vec![2, 3, 4, 3, 4]), 4); +} + +struct Solution; + +impl Solution { + pub fn alternating_subarray(nums: Vec) -> i32 { + let mut result = 1; + let mut r = 0; + let mut one = 1; // 1为1 + for i in 1..nums.len() { + if nums[i] - nums[i - 1] == one { + result += 1; + one *= -1; + } else { + if nums[i] - nums[i - 1] == 1 { + result = 2; + one = -1; + } else { + result = 1; + one = 1; + } + } + + r = r.max(result); + } + + if r == 0 || r == 1 { + -1 + } else { + r + } + } +} diff --git a/src/bin/longest-common-prefix.rs b/src/bin/longest-common-prefix.rs new file mode 100644 index 00000000..06cab07b --- /dev/null +++ b/src/bin/longest-common-prefix.rs @@ -0,0 +1,55 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + assert_eq!( + "fl".to_string(), + Solution::longest_common_prefix(vec![ + "flower".to_string(), + "flow".to_string(), + "flight".to_string() + ]) + ); + assert_eq!( + "".to_string(), + Solution::longest_common_prefix(vec![ + "dog".to_string(), + "racecar".to_string(), + "car".to_string() + ]) + ); +} + +struct Solution; + +impl Solution { + pub fn longest_common_prefix(strs: Vec) -> String { + if strs.is_empty() { + return "".to_string(); + } + + let (mut result, mut index) = (Vec::new(), 0usize); + loop { + if index >= strs[0].len() { + break; + } + let i = strs[0].as_bytes()[index]; + let mut flag = false; + + for j in strs.iter() { + if index >= j.len() || j.as_bytes()[index] != i { + flag = true; + break; + } + } + + if flag { + break; + } + + result.push(i); + index += 1; + } + + String::from_utf8(result).unwrap() + } +} diff --git a/src/bin/longest-consecutive-sequence.rs b/src/bin/longest-consecutive-sequence.rs new file mode 100644 index 00000000..24858a43 --- /dev/null +++ b/src/bin/longest-consecutive-sequence.rs @@ -0,0 +1,97 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() { + // assert_eq!(Solution::longest_consecutive(vec![100, 4, 200, 1, 3, 2]), 4); + assert_eq!( + Solution::hashset_longest_consecutive(vec![0, 3, 7, 2, 5, 8, 4, 6, 0, 1]), + 9 + ); +} + +struct Solution; + +impl Solution { + /// 使用哈希集合 + /// 遍历到一个数的时候,挨个+1看集合中是否存在,存在则说明是连续的。 + /// 优化:如果集合中是 [2,3,1,4,5] 的话,我们遍历2的时候,检查3,4,5是否存在,但是遍历到1的时候,要检查2,3,4,5是否存在,因此我们不需要在2的时候进行检查。因此遍历到i时,如果i-1存在,则i的时候不需要检查。 + pub fn hashset_longest_consecutive(nums: Vec) -> i32 { + let mut set = nums + .iter() + .map(|x| *x) + .collect::>(); + + let mut ans = 0; + + for mut i in nums { + if set.contains(&(i - 1)) { + continue; + } + + let mut r = 0; + while set.contains(&i) { + r += 1; + i += 1; + } + + ans = ans.max(r); + } + + ans + } + + /// 使用hash表,保存值对应的最远有边界,比如 [2,3,1,4,5], 2的最远右边界就是5,1的最远右边界也是5. + /// 初始化的时候,每个数的最远右边界为自己。 + /// 遍历的时候,如果遍历到i,如果i-1存在,则说明i是一个连续序列的起点,获取到对应的右边界 right1 + /// 如果right1+1存在, 获取到right1+1的右边界的值right2,如果 right2 + 1 存在,则获取right2+1的右边界right3,如果right3+1存在... + /// 此时i的右边界则为最后一个值 + pub fn hashmap_longest_consecutive(nums: Vec) -> i32 { + let mut map = nums + .iter() + .map(|x| (*x, *x)) + .collect::>(); + + let mut ans = 0; + + for i in nums { + if map.contains_key(&(i - 1)) { + continue; + } + + let mut right = *map.get(&i).unwrap(); + + while map.contains_key(&(right + 1)) { + right = *map.get(&(right + 1)).unwrap(); + } + + ans = ans.max(right - i + 1); + map.insert(i, right); + } + + ans + } + + /// hash表存数字i所在的连续最大长度值 + /// 对于数字i不存在,则i的值为 i-1 与 i+1的最大值 +1 + /// 然后更新i-1、i+1、i + fn dp_longest_consecutive(nums: Vec) -> i32 { + let mut map = std::collections::HashMap::::new(); + let mut ans = 0; + + for i in nums { + if map.contains_key(&i) { + continue; + } + + let left = map.get(&(i - 1)).and_then(|x| Some(*x)).unwrap_or_default(); + let right = map.get(&(i + 1)).and_then(|x| Some(*x)).unwrap_or_default(); + + let current = 1 + left + right; + ans = ans.max(current); + map.insert(i, current); + map.get_mut(&(i + right)).map(|x| *x = current); + map.get_mut(&(i - left)).map(|x| *x = current); + } + + ans + } +} diff --git a/src/bin/longest-continuous-increasing-subsequence.rs b/src/bin/longest-continuous-increasing-subsequence.rs new file mode 100644 index 00000000..f314a30d --- /dev/null +++ b/src/bin/longest-continuous-increasing-subsequence.rs @@ -0,0 +1,415 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + assert_eq!(3, Solution::find_length_of_lcis(vec![1, 3, 5, 4, 7])); + assert_eq!(1, Solution::find_length_of_lcis(vec![2, 2, 2, 2, 2])); + assert_eq!( + 4, + Solution::find_length_of_lcis(vec![1, 3, 5, 4, 2, 3, 4, 5]) + ); + assert_eq!( + 7, + Solution::find_length_of_lcis(vec![ + 1334, 1500, 4169, 724, -3522, 4358, 1962, -536, 705, 3145, -1719, 1827, 4961, -4509, + -2005, -3058, -173, 436, -2609, -396, -1098, -4847, -4708, -2618, 2421, 3716, 4718, + 4895, 447, -3274, -229, -3462, -3131, 4912, 667, 1299, 2035, 4894, 3703, -1189, -3678, + -4667, 2673, -336, 141, 2711, 3253, 1868, 547, 2644, -2338, -2243, -4963, -2141, 3723, + 4741, 2529, -4222, -2684, -1965, -2810, -3158, -4712, -4894, 4040, 3942, 4264, -2352, + 2446, -1195, 890, 1729, -630, 350, 6, -3899, -607, -1452, 4629, -2377, -916, 4954, + 3756, -3160, -34, 2376, -1069, 1308, 1944, -2561, -374, -3677, 537, -3462, 1118, -2918, + -2071, 1541, -167, -3885, -361, 4658, -2296, 4930, -1023, -2694, -3327, -2614, 21, + 3745, 1924, 4072, 1270, 829, 1777, 573, 97, 1512, -1014, -1710, 4161, 3636, -2645, + -233, -1345, 574, -969, -2948, 2350, -3850, 1941, -3276, -1034, -1570, -3893, -4809, + 3007, -3663, 457, -2713, 2753, -4617, -55, 3909, -2791, 4758, -779, 3588, 1422, -54, + 2506, -1970, 1413, 4168, -4100, -2409, 3762, -3345, 2410, 1359, 2624, -4463, -3452, + 1483, 2595, -959, -1398, -650, -4709, -4164, 4374, -3980, -404, -979, 2348, -1801, + 4668, -516, 3281, -266, -4947, -3001, 1418, 2938, 1900, -1212, 3127, -4533, -1272, + -107, -352, -2517, 2807, -2579, -690, 1617, -2187, 4514, -691, 2616, 3935, 2451, -4400, + 249, 1519, -3444, -2202, -4697, 1224, -3992, 844, -2391, -11, -2298, -1805, -4515, + -1907, -657, -4477, -3413, 4314, 4503, 2448, 200, -1542, 1618, -4420, 4796, -202, 281, + 4589, -4202, 3009, 2157, -4528, -1378, 3538, -2708, 1038, -821, 3190, 4657, 2958, 1191, + 4815, -2112, 4156, -3489, 1202, -2366, -728, -4945, -4672, -2354, 1362, -114, 3875, + 3433, 4869, -4858, -1156, -3584, -3119, -3002, -4678, 3651, -4979, 699, -1443, 3476, + 2892, -611, 75, -4288, -2400, -2490, -3997, 1869, 2861, -312, -1599, 4789, 255, 1423, + 2, -4415, -818, -4715, 2088, -3574, 3617, -1243, 4832, -4068, -831, -2846, 721, 2189, + 4976, -3671, -2632, 3692, -3575, -4445, -1566, 1549, 2441, 4512, -4855, 3060, -3282, + -1247, 1139, -2577, 1279, 996, 1687, -2471, -2451, 2437, 4866, -2051, -4807, -1805, + -1703, -4584, 3286, 1105, -512, 1282, -2545, 734, 3114, -3299, -3684, -4329, 786, + -2737, -687, -645, -3815, -4947, -4088, -4192, -3168, -4055, -687, 2756, 3321, 4558, + -1354, 2982, -4519, -856, -1804, -4778, 2129, -2839, 535, -4550, -3827, -4534, -2956, + -3341, 1292, 1439, 2253, -4976, 1154, 4510, -255, -4351, -1814, 3313, -526, 3022, + -2832, -982, 3787, 4905, 2958, 2391, -4798, -1375, 1477, -586, 4314, 824, 4334, 874, + -628, -4841, -3167, 3070, 2487, 3297, 2518, 3177, 2773, -2730, -3237, -2332, 2192, + -1015, -1898, 3480, 4213, 2627, -198, -901, -4473, -2375, -3457, -3076, -3977, 4972, + -1939, -819, -3997, 2432, 2505, 2593, -2275, -1969, 3492, -4858, 2222, -3714, -1936, + 2900, 4187, 3360, -2587, -4026, -730, 4170, -4765, -4167, 4711, 760, 3896, -333, 2285, + -2450, -4860, -1306, -2305, -3376, 3019, -2875, 1576, -3306, -2342, 1302, 2371, -2534, + -322, -2407, -1149, 484, -3982, 3464, -3881, -1848, -2200, 3087, -3940, -3074, 4010, + -243, -2830, -4685, 4576, -4773, -2957, -2242, 2164, 109, 2882, 2086, 4565, -1513, + 4577, -526, -2375, 627, 629, -3072, 423, 3520, 1902, -38, -4877, -404, -1263, -1739, + -4805, -2475, -3736, 3260, 1202, 3116, 30, -4674, 4011, -4229, 1411, 547, -3847, -3480, + 4790, -76, -4812, -3237, -60, -4149, 3662, -1171, -4100, 2713, 3958, 2578, 3365, -1993, + -3523, -3800, 1058, 1439, -2697, -2240, 4357, -2676, 1477, 108, -3887, -113, 4801, + -2150, -540, -2572, -2007, 2384, 4405, 1540, -3889, 3704, -2165, -2644, 1072, 4350, + 3823, -515, -4444, -1784, -3374, 4357, 3526, -1643, 4337, -1729, -1131, 4361, -2104, + -1978, 4617, -4888, -2283, 3696, -3415, -959, -577, -871, -771, -435, 1559, 3932, + -2704, 4855, -2947, 1962, -1416, 4734, 1654, 1972, -3543, -631, -2468, -2037, -2393, + -2517, -4089, -3365, -4933, -2152, -325, -2062, -2777, -2858, -1246, 1511, -2259, + -4825, -3541, 2825, -1779, 2870, -3374, -3066, 205, -3217, -1150, 2398, -2721, -2299, + -2807, -2266, -3363, 1534, 556, -3007, -4824, 705, 1962, -4452, 881, -4700, -587, 1641, + 4855, -145, -1858, -3538, 2611, -4123, -4576, -2322, -3248, 3443, 3296, -2327, -4960, + 4313, -4125, -4928, -2182, -4390, -3983, -68, 3112, -4305, -1831, -1169, -4960, 1488, + 3685, 4090, 4497, -2411, 990, 145, 4353, 4314, 3651, 1740, -2956, -3742, -4665, 3759, + -3808, 2605, 264, -2819, 3503, -1171, -1225, -4392, 4292, 997, 2549, 4556, 561, -3373, + 1467, 4541, 1129, -3760, 2813, 4174, -4399, 1077, -4785, 3683, 3213, -1008, 824, 601, + -1608, 759, -2330, 1428, 3027, -916, -4925, 3786, 498, -30, 1287, -1153, -2396, -4497, + -3779, -2337, 706, -2637, 4010, -2829, 2489, 3240, -2836, 542, 2619, -4087, 2591, 1704, + -3182, 4232, -4250, 205, -25, -3461, -4697, -3578, -3902, -3753, -1416, -1352, -2029, + 2864, -2087, -3925, -3455, 3712, 2546, 3678, -3231, 262, 3519, -1015, 3289, 944, -2135, + 3540, -1755, 508, 3318, 2870, 4601, 3323, -3868, -528, 2152, 87, 3570, 4763, 4901, + 2103, -577, -1473, -3400, 1969, -985, 565, -4972, -3457, 347, -2912, -2057, -2363, + -2591, 1463, 49, -319, -3412, -3658, -4392, -2940, -3779, -3242, 4954, -4112, -854, + -4310, 2949, -2157, -3570, 620, -4252, 2067, -464, -4217, 3035, -2774, 185, 2038, 4853, + 629, -3776, 748, 4923, -1641, -2743, -234, -56, -45, -1682, -2274, 411, -3975, -4645, + -3999, -2451, 4496, 3584, 4515, 2964, -1658, 3075, 2913, 1142, -3804, -3052, 72, -4574, + -394, 1173, -571, -2596, 1705, -4374, 4812, 4375, -4907, 1565, 1036, -264, 4141, -4186, + 994, 3256, 1652, -1064, -4162, -4518, -3645, -3985, -3869, 3230, 2841, -375, -2989, + -2363, -814, 4690, -3350, 662, -3366, -4107, -4647, -3584, -1548, -992, 2262, -2767, + 454, 1303, 1634, 1303, -744, -4852, -3876, -2683, -787, 2109, -972, 4200, -3920, -3682, + 1858, -950, -845, -3639, 264, -3097, -1324, 4643, 1909, -98, -1439, 3489, -52, -3718, + -1347, -4326, -2780, 402, 1923, -1169, 4369, -1122, -4741, 4008, -2381, -1029, -4997, + -3055, 4781, 1504, -2608, -2315, 313, 1698, 589, -2278, 938, 4037, 1410, -3539, 1234, + -2492, 4961, -1041, 1493, -3485, 269, -63, 3869, -4942, -300, -1029, 1264, 117, 1215, + -445, 2815, 3330, -1961, -4788, 4288, 3082, -3046, 1085, -4290, -516, -226, 3380, 4815, + 951, 1541, 3115, -3321, 2110, 898, -1927, -4212, -1023, 3132, 4956, 3689, 1113, -4992, + -2059, 790, -3277, -3637, -4972, 184, -222, 2200, 71, -3115, -3026, -3929, -3667, + -2133, 1153, -705, -2832, -4175, 4676, 629, 3650, -2402, -1691, -307, -314, -4920, + -4884, -2751, 1667, -3472, 1679, 2864, 4421, 3405, 3826, 1816, 2516, 2726, 3666, 4087, + 2681, 4964, -3660, 686, 1021, -3338, -279, 1064, 4309, -4585, 2902, 4873, 2124, -1059, + -2255, -3238, 3423, 2531, -194, -2732, 4318, 602, -3093, -693, -1519, -3988, -3864, + 1630, -886, 1809, -916, -1444, -2710, -3707, 4996, 4152, -3946, 345, -292, -4752, 2491, + -1288, 131, -4886, 1439, 2958, -278, 4704, 1995, -3948, 269, 2479, 3238, 1423, 2918, + -4134, 2659, -2502, 3486, -3804, 2462, 1633, -2842, -2978, -3854, 3392, -1963, -1075, + -4353, 4458, 1602, -4193, -902, 2830, 4292, -400, 2278, -4201, 3352, -4552, -1118, + -4460, 3315, -425, 3762, 4567, -2664, 3397, -3582, 4897, 828, -1149, 1816, -770, -551, + 1925, -4342, -4771, -480, -4060, 4560, 147, 162, -3345, -4325, -4208, -2639, -3246, + 1398, -1854, 3714, 1946, -3812, 4569, 3638, 2663, 75, -485, -3479, -4525, 615, -4472, + -1766, -2430, -4095, 4464, 4557, 3962, -839, -4476, -2451, 2469, -4670, -3077, 3350, + -667, -2075, -4090, 4737, 1336, 3337, -3722, -2607, 2636, -4286, 3164, -3409, 4949, + 4135, -2495, -1663, -4996, 1337, -2377, 3664, 4970, 608, -4432, 4281, 2085, 4152, 3373, + 3652, 3194, 4876, -1174, 3396, 2572, 1249, -360, 4174, 3819, -4057, -2389, -3059, + -4711, 3419, 565, -1195, 2585, 1216, -3550, -3385, -2391, -3936, 4166, 1893, 1074, + -1491, -4700, 4695, 4573, 589, -1839, -3828, 2968, 2358, 1031, 1268, 4426, 3510, -4578, + -4226, 3779, -4090, -1448, -818, 391, 495, 764, -4126, -3636, -98, 3255, -540, -4526, + 1972, 1821, 1122, 547, -3423, 4789, 605, -4805, 2594, 2950, 1343, -4246, -2519, -3988, + -3328, -1561, -1572, 912, 4762, 967, -592, -585, -3092, 2223, -3241, 1434, 204, 4486, + -681, -4042, 945, 1806, 3166, 3700, -3633, 2692, -3213, 3532, -4444, -4026, -1553, 21, + 3283, 1222, 4331, -2624, 3583, 1948, -2277, 2982, -2982, -224, 4220, -3889, -2818, + -1144, 4490, 3925, -676, 1486, 4677, 969, -3357, 2534, 677, -2332, -3932, -3009, -2804, + 2783, 1828, 2727, 4426, 871, -4303, 2612, 3703, -3973, -3592, 545, 4508, 2185, -4762, + -763, 1443, -3687, -2499, 3850, 128, -2889, -1350, 3149, -3808, -3546, 869, -4319, + 2465, -4733, 2713, 4793, 3634, 472, -4028, -2170, -99, 3442, 177, -1123, 770, -4298, + -636, -3619, 1590, 3823, -2763, 3023, -2821, 1595, -4831, -2673, -2958, -3690, 3182, + -3942, 2926, 4487, -3330, -2472, 651, -2742, 2213, 4860, 783, -3714, -2258, 3610, -528, + 2128, 3434, 841, -4282, -1497, -133, -135, -4062, -3119, 4257, -2250, 3614, 3598, 3458, + -2339, 1063, -2244, -4193, -4722, 4489, 4435, 1365, -2925, 2586, -3614, 2833, 3360, + -1670, 1048, 3928, 4492, -2567, -1160, 1766, -3265, 4810, -3401, -3163, -3108, -3018, + 2328, 4352, -3631, -3756, -3206, 1608, 4252, -3353, 2432, 4535, 2208, -1736, -1503, + -1757, 2649, -2985, 1841, -4811, 1100, 4812, -4352, 4523, 4851, -526, 3633, 4891, 2200, + 4854, 4990, 697, -81, 2780, -2422, -2069, -2456, -1660, -1513, -4101, -2475, 3483, 538, + 2492, 1193, 3252, 11, -3440, 834, -3160, -3503, -2215, 3529, -3460, 3805, 3791, -1608, + -1790, -1451, -3422, 1979, -4029, 4277, -4927, -4807, -3380, -3503, -1174, -3724, 4790, + 1582, -1422, -3841, -4582, 1489, -4841, -1551, -2076, 4072, -4620, 2008, 2967, -4792, + 1477, 3503, 370, -2393, -804, -2926, -1278, -2389, 4019, 3761, -3944, -2110, -3837, + 1683, -1284, 4932, 452, -2259, -46, 1813, -2138, -4604, 460, -4385, -4096, -2401, + -4864, -320, 4198, 2032, -613, -2416, 2240, -1483, 2006, 3670, -4759, 3882, 249, -1477, + -3242, -2895, 4621, 2095, 2296, 4916, 678, -4822, -1421, 58, 2577, -2250, -993, -1271, + -919, -2005, -2322, -324, 2753, -4101, -3216, 565, -1907, -1392, 1172, -3757, 4929, + 2514, -4832, 55, -3809, 973, 3922, 1748, 651, -4014, -2856, 1446, -3423, 1517, -371, + 4916, 874, 791, 469, -2088, 3146, -4307, 4091, 4815, 1949, 1857, -4360, 1052, -4764, + 3551, 4487, -3774, 3162, 1955, -1817, 3394, -4820, 1097, -1935, 2065, -2487, 4261, + -2422, -3922, 1878, -860, -389, -3053, -2555, -4830, 4975, -1511, -250, 1149, -1667, + -1135, -2786, 2282, 2007, 2432, 3896, 1367, 3522, -118, -3190, 2641, 2231, -2813, 1705, + 1479, 1321, 1538, -3649, 4447, -792, 4646, -2724, 759, -4811, -4578, 2666, 3486, -1545, + -2972, 4614, -140, 4253, -3223, -3652, -2497, -4139, -2569, 4082, -2545, -803, -2894, + 3752, 821, 2296, 1281, 1021, -545, 947, 2124, 3318, 4135, -3624, -3226, 4859, -2, + -2926, 4253, 1922, -4365, -3357, 3888, 3153, -1768, -253, 3680, 4926, 678, 1450, -199, + -39, -801, -4145, 1363, 716, -4427, -3439, -1755, 1473, 3274, -3450, -647, -3819, -713, + -2301, 3110, 3643, 2465, 2172, -2471, 4981, -2888, -1524, -619, 3247, 1890, 1671, 3805, + -2628, -4968, -1011, 4320, -1835, 431, 4658, -3707, 2206, 1578, 1948, -2794, 2171, + 3166, -1604, 1697, -3980, -1306, 529, -212, -4891, 2984, -3031, 3978, -3383, -985, + 1626, -1316, 4168, 2906, 928, -2903, 3118, -610, 199, -3215, -514, 4199, -2580, -4290, + 3271, 813, 2415, 1085, -4682, -1420, -3669, 2267, 3387, -1556, -1814, -493, -640, 2827, + 3074, 1431, 2152, -4729, -4732, -307, 4885, -4663, -3689, 2604, -2323, -4594, 2768, + 4022, 4413, 0, -4458, 2537, -4962, -3612, 2355, -1711, -3353, -1819, -1907, 1584, + -4013, -4239, -4507, 3217, 4501, 2482, 4447, 665, -4247, -2896, 84, 4095, -1475, -4779, + -1036, -3219, -128, 3106, -1344, -1657, -2407, 2080, 1080, -132, -3589, -1287, -4032, + -1749, 2216, -2921, 3768, 2040, -3469, -2067, -1221, -4337, -2741, 1653, 2936, -2905, + -635, -3126, 2720, 1835, 680, 3976, 3455, 725, -929, -192, -1441, 4156, 602, 2832, + 2905, -4560, 2375, -3438, -2115, -3038, -3920, -3164, -4203, -3798, -4492, -4920, 340, + -2924, 4058, -3507, 2740, 3546, -4526, -227, 4097, 3880, -1665, -3928, -1600, -4293, + -2045, -4334, -859, -1412, -2519, 2168, 3315, 4396, 1225, -3991, -2988, 3136, -3545, + 3762, 43, -4258, -4979, 2922, -488, 4248, 1018, 2368, -1283, 4714, 2650, -1710, -1665, + -2241, -1831, -3105, 303, -2360, -3021, -801, 4105, -209, 3661, 3681, -1348, 3753, + -967, -2971, 987, 2042, 1253, -4917, -3580, 814, -2282, -2756, -3937, 2229, -4348, + 3864, -231, -4530, 5, -3953, -3406, -3513, -674, -1724, -3677, 1540, 2679, -1010, + -2412, -290, 4271, 2945, 4221, 3470, -4817, -1411, -1045, -22, -221, 6, -1738, -4865, + -1513, 2196, 4033, -2912, -2065, 4779, 993, -210, -38, 3965, -3999, 4105, -3193, -433, + -2331, -1866, -2329, -3543, -2002, -1455, -1403, -782, 3838, -156, 2372, 3563, -3972, + 4264, 3801, -277, -1510, 2604, -3399, -773, -3803, -1308, 4771, -4637, 4301, -2637, + 2721, -1435, 2421, -1555, 3610, -4505, 1741, 22, -3188, 4151, -1985, 3055, -1607, 3738, + 279, 4882, -3392, -2346, -1178, -2293, -755, -3662, -4856, -2710, -3661, -1846, -396, + -377, -2775, -4922, -3276, -3019, -2670, 4733, 3223, -4406, 4130, 3846, -13, 4445, + 3805, 3616, 750, -4511, 2338, -3037, 3135, -303, -2791, -3370, -1776, -3092, 1737, + -526, -3080, 2372, -4707, -1145, 1734, 4561, -3944, 2606, 3184, 2075, 3382, -881, 1741, + -4568, -316, -2221, -2721, 3283, -4333, -4164, -875, -882, -2263, 3028, -2881, -4423, + -4263, -909, -4444, -2205, 1060, -3099, 3793, -1568, -2864, -420, -125, 907, -3816, + 3074, 3719, 1790, -4524, -4959, -1649, 3329, 1290, -2026, -1928, -1409, -2811, 787, + -3510, -1761, -107, -1947, 2063, -4319, 903, 2005, -824, 3479, -3305, 1139, -2532, + -1002, -3917, -1361, 4515, 2621, 4993, 826, 722, -1162, -172, -2419, -601, 3978, -3109, + -3977, 1943, -166, -757, 2349, -2298, 3707, -4498, 141, -4313, 3346, 891, -363, 3413, + -3600, -2184, -3310, -1838, 3935, 4126, 4410, 4877, -3618, 1260, 2189, 1705, -1126, + -2337, -4278, -2805, -2434, 1360, 1038, 3588, 2811, 3245, 4467, -2575, 1867, -1811, + -4458, -1937, -3453, -4498, 4617, 4099, 23, 2226, -3797, -4952, -3949, -3430, 3636, + 4458, 967, 3456, 4405, -3469, 4962, 1819, 2975, -4444, 2531, -3505, 3044, -4409, 1803, + -1612, 3915, 2450, -2681, 1272, 791, 4383, -4867, -3225, -358, -1431, 3300, 2954, + -2922, -1415, -2743, 333, -4107, -4510, -4897, -250, 2233, -4278, -729, 4611, 3990, + -4662, -3359, -1742, 4047, -2648, 4658, -4521, 302, -2317, 3990, -4998, 568, -578, + 1895, 1135, 3008, -2639, 1742, -2806, -1301, -1812, -4822, -958, -3643, -1059, -3153, + 2469, 1345, -620, -3087, -36, 710, -4939, 385, -4927, 2504, 4462, -2297, 3102, -3931, + 154, -1471, -3448, -2926, 4149, -1270, -2756, -4156, -1951, -882, -935, 1363, 4552, + 3773, 3470, 4731, 1747, 2511, 869, -602, -4502, 2103, 2352, 679, 3053, -1957, -478, + -3912, -3437, 834, 4850, 2022, 2240, -3089, 4492, 651, 3580, 477, 2616, 4876, 4178, + 220, -385, -2652, 1798, -2821, -3365, 1857, -2117, -3338, 3902, 3262, 4420, 4770, 4022, + 4273, 841, -2314, 3888, -1083, -3283, -3108, -1302, -3733, -3251, -4935, -4611, 1932, + 619, 1081, -2997, 4130, -1972, 3631, -411, -1848, 3630, 4172, 4864, 1407, -2705, 428, + 4681, 3490, 1610, 1177, -3929, 236, 1459, -4357, 1840, 2633, 2037, -1107, -2370, -4726, + -2007, 3782, -2797, 2461, 3290, 4662, -2693, -4003, -3849, 3423, 3890, 1717, 1640, + 3703, 566, -117, -1339, -2341, 3245, -4614, -2349, -2235, 4601, 1840, 2209, -3503, + 2283, 4250, 3058, 3421, -4825, -4419, 1787, -1729, -713, 2999, -2496, -21, -2862, + -4300, -4470, -2539, -2882, -4795, 2540, 3828, -541, -3378, -602, -1240, 2098, -2065, + -4519, -4386, 4567, 3493, 3596, 4161, 2746, -4462, 2670, -4462, -3524, -3445, -83, + 1371, 1760, 752, -1242, 433, -2745, 4065, -4274, -2599, -1966, -2241, -4607, -4452, + 2273, 3792, 1193, -2067, -4863, 2103, -1310, 3211, -1306, -332, -2373, 2498, -4011, + 248, -1121, -3353, -3851, -4069, -4331, -4125, 598, 449, 436, -401, -4877, -3557, + -3269, 3154, -2139, -566, 4385, -1033, -4184, -3607, 1704, 4866, -4047, -4692, 3223, + 3684, -4208, -2333, -4952, -2531, -1070, -4189, 4814, 1090, 427, -1257, -3396, -4401, + 1474, 2195, -4494, 158, 2589, 4858, 2809, 2889, -3553, -4960, -1182, 4364, 2975, -4974, + 89, -2497, -4934, 1412, 1840, -2430, -324, 395, 3641, 4986, 2651, -3891, 3187, -4917, + -3915, -1610, -3750, 3686, -245, -3619, 3128, 502, -723, -4138, 1424, -1435, -1128, + -4168, -4115, -572, 1646, -4111, 1478, -4117, -75, -3735, -3740, 45, -4222, 821, -1145, + -2480, -2073, -227, 134, 2251, -2325, -1664, 1334, -3999, -2263, 4310, 974, 2590, + -4644, -3929, -2920, -4065, -2855, 2282, -3175, 3718, -1427, -288, -1963, -2, 4905, + 2162, -3283, 3692, 4539, 3047, -4054, 4103, -4769, -885, -4161, 858, -4171, -2355, + -1606, 2199, 4645, -728, -4325, -3138, -2928, -1227, -2520, -3762, 1897, -1458, 4608, + 4203, -1723, 1125, -4866, -3599, 4078, 3382, -4831, -4264, 2478, 2939, -3862, 3721, + -3574, -4337, -3323, -3425, 1724, 981, 2700, 2961, 3862, 1002, 3448, 95, -4316, -984, + 137, 4507, -1007, -3716, -2056, -4741, -4179, 2058, -357, 2668, -4323, -4881, 4857, + -1959, 3891, 264, -3377, 1915, 3072, 2929, -4159, -285, 2615, -2464, -43, 2759, -4300, + -1548, 93, -759, -3171, -2552, 227, -3202, 1224, -4676, -2726, 3133, -2115, 38, -2830, + 1862, -2371, 84, -3091, -122, 1923, 2085, 4400, -1976, -807, -1895, 4412, 765, 767, + 407, -4323, -1216, -4296, -210, 4834, -4109, -4379, 3085, 2734, 190, -4458, 2998, + -2914, -2982, 621, -4576, -2403, -3624, -746, 4669, 3108, -2073, -2507, 1068, 1366, + 4102, -2562, -2400, -4181, -682, -2710, -16, 1339, -2444, 808, -368, -3522, 1814, + -1213, 2239, 3074, 20, -4173, -2446, -3012, 2441, 1798, -1358, 4002, 1321, -4896, + -1054, 2056, 3509, 4833, 2708, 4761, 1533, -4314, -196, 1385, -4858, 3842, 2260, -2839, + -3380, -657, 4578, -3813, -4887, -1937, -409, 934, -4585, -4344, 4761, 12, 3411, -3041, + 1251, 3738, -1630, 1124, 507, 3007, 2584, -4049, -1899, -511, -42, 441, -3210, 2013, + -4588, -145, -3940, 2093, 3472, 402, -2324, -1457, 2373, 1266, 2651, 275, -3472, -4468, + -4239, 469, -2497, -2271, 2107, 2892, -2549, 2953, 3392, -2430, -1481, 4472, -1593, + -2506, 4505, 3440, -4617, -738, -3591, 3607, 3038, -640, 471, -3829, -4346, 4947, + -3486, -477, -3771, -4511, 1766, 2887, 4756, 1632, 2470, 739, -4334, 3522, 2283, 3160, + 2553, -295, 2091, -3741, 386, -3313, -371, -4958, 3317, -2955, -2644, -1612, 452, + -1846, -4534, -3167, 2760, 1919, 631, 1738, -3733, 776, -3902, -686, 1320, -1947, -993, + 1469, -784, 4722, 4842, 4007, 463, 1260, -4053, -1207, 3630, 3717, -1957, -3624, 314, + 1626, 2117, -3666, -4380, -829, 1792, 3964, 4154, 3866, -307, -4336, -1225, -2000, + -2788, -3900, 2551, 476, 1379, -4057, 2877, -1211, -4639, -3615, 3272, -3566, 144, + 4561, 563, -496, -2054, -1112, -4692, -2843, -3570, 123, 1464, -926, -654, -1163, + -3019, 318, 1611, 1292, 2591, -1168, 2123, 1461, 1991, -3539, 2330, 3498, 2369, 2291, + 3400, -821, -883, -2683, 4914, -3405, -3559, 936, -3133, 2028, -3547, 2909, -1027, + 2981, -3497, 1569, 1816, -3117, 367, 385, 3402, 230, 2157, 3681, 567, 3310, -3134, + -1313, -1829, -1523, -3755, -2236, 1238, 2671, -2953, 1115, -408, 2311, -2343, -3595, + -4947, 2171, -4420, -2260, -2470, -1325, -680, 790, -1623, -4002, 1586, -3396, -511, + 4631, 4744, 3388, 1610, 3718, 1919, 3259, 927, -391, 3119, -3521, -2284, 1300, -3604, + 1853, -3542, -4170, -407, -4194, 4849, -146, -728, 1160, -2706, -2946, 1333, -4854, + -771, -4529, -4572, -4441, -2759, 4421, -2312, 1366, -2967, 1685, -2730, 329, -2739, + -2140, -2792, 3982, -2838, -2494, 1878, -3021, -3103, 2887, 1538, -531, -4217, 2540, + -2205, 2266, 3633, -1491, -443, -2683, 1134, -2947, 3135, -2742, -2407, 2843, -3307, + 1466, -2049, 3140, -3906, -2063, 174, -2488, 1097, 4551, -2305, -3183, -1508, -3708, + -4763, 2530, -4387, 296, -3290, -2611, 628, 809, 3786, -3256, 3840, 3182, 3569, 1120, + 2393, 1292, -38, -786, -2473, 1807, -1806, 3705, -287, 2011, 3913, 1693, 4664, 1203, + 3995, 2762, -619, 1946, 4909, -3952, -3232, 1624, -2489, 2954, -765, -3873, -367, 3240, + -3138, 127, 2577, -1183, -2660, -4858, 100, 3400, 1558, -3524, -1846, -4065, 1430, 831, + -3705, -1463, 623, 2922, -2073, 3029, -4789, 1211, -3246, 1880, -2747, -1707, -3679, + -4215, 1528, -4557, -4000, -4445, -329, 4270, 2452, 4375, -369, -1360, 3934, 3040, + 2986, 3834, -752, -3461, 3765, -2204, -4688, 2262, 52, -4269, -1013, -536, -2443, -752, + 4556, -4830, 450, 2182, 2301, -1707, -901, -1668, 4044, -2669, -4925, -3996, 4050, 26, + -934, -3262, 4801, 4623, -1157, -4559, -1620, 4695, 2918, -1341, -3637, -2372, 1329, + -3912, 3854, 3613, -21, 3569, -4334, 2679, 2577, 2837, -1598, -1885, -1708, -3277, + -2128, 4448, -4677, -3847, 948, -605, 197, -492, -2092, 2411, -1007, 2665, 1781, -1798, + 2610, -172, 2256, 2705, 3965, 3023, -4231, -3285, -4747, -3195, -1316, 4478, -2855, + -3160, -4167, 4285, 1900, -4032, -1006, 1633, -1115, -4652, 3281, 3032, 1256, 4910, + -4128, 3982, -1099, -2694, -4365, 2860, -2529, 4527, 2137, 3343, 4768, 3233, -1005, + 4171, 2603, 3942, 3011, 2879, -3966, -488, -407, -4470, -839, -1766, -4742, -3074, 906, + 191, -557, 1188, -4773, -2281, 1484, 224, 4093, -4565, -1776, 3094, -1418, 3867, 3627, + -2995, -3854, -2314, 1589, -4460, 3237, -2150, 3759, 4578, 3956, -2323, -2597, 3042, + 1300, 811, 225, -3857, -3405, -3984, 1615, 3804, -3994, 3368, -3359, -4665, -4302, + -3675, 3313, 3023, -2688, -382, 3457, 3396, 3339, -3914, -2906, 2846, 2043, -3478, + -2089, 1280, -1545, 1358, 1847, 3870, -4010, -1127, -673, -1587, -1546, -3104, -2528, + -550, 2241, -359, 646, -1475, 3213, 1824, 2929, 3695, 403, -2406, 2993, 1067, -2813, + -360, 79, -4959, 3125, -2466, -140, -2000, -93, -2379, 2692, 293, 117, 2717, -4597, + -1057, 2893, -4361, 4011, 1925, -972, 4978, -4252, -2150, -2108, 1444, -4346, -1377, + -647, -2964, -3453, -3654, -4174, 1061, -1096, -4762, 2571, 1886, 1405, 299, -2944, + -3272, -3733, -1249, -2981, 4991, 3166, 717, 846, 2093, -1813, -3579, -2088, 1867, + 3299, -2556, 4897, -3799, -1672, -58, 2104, -3232, 4768, 1641, 1296, -3738, -4280, + -3756, 2918, 4625, -3781, 2584, 3174, -4016, -4541, -1851, 2014, 695, -2497, 32, -1149, + -3463, 1814, 3363, -349, -3781, -710, 917, -3317, -3082, 1584, 2252, -1414, -3731, + 1248, -2863, -2603, -4576, -1832, -4973, 3148, -3007, -4618, 4271, 2669, -4107, -4123, + -3986, 4104, -4516, -2057, -3505, 1811, -3707, 3892, 1798, -3010, -3701, -110, 3493, + 4074, -3451, -1226, 4314, -4827, -931, 4218, 1865, 1833, 238, 4911, -1748, 1463, 1508, + 149, -1912, -2755, 1231, -3080, -4894, 4271, -2632, 1421, 258, -843, 4647, -18, 3238, + -878, 2723, -4094, 3706, -4811, -3844, -4655, -2649, 1923, 2118, -3450, -2903, -3164, + -4409, -1594, -490, 813, -349, 880, 2844, -257, 2741, -3755, -422, -51, -3295, -486, + 4785, 4227, 3624, 2204, 3356, -1083, 1227, -4445, -4898, -714, 4468, -3302, 3979, + -3589, -2511, -4242, -1510, -4225, 3410, 2132, 2089, 2296, -3050, -1888, -4878, -2471, + 2672, 836, 3277, 553, -1024, -4330, 4085, -2348, -3249, -4603, 4751, 4001, -4565, 1693, + 72, 2916, 1716, 328, -3489, -2875, -3162, 2296, 3939, -3456, -3944, -2174, -2098, 1758, + -412, -2979, -2414, -892, 4777, -2372, -3021, 1947, -2451, -3720, -1755, 128, -938, + -4574, -281, -4323, 4091, -953, -1215, -1769, 2406, 3684, -3046, 1769, -291, 2956, + -2579, 945, -1535, 1016, -3140, 1497, 3335, 190, 677, 3049, -3995, 2886, -1612, 3675, + -1857, 2377, -4870, 3487, 1555, -2518, 253, 0, 2754, -4711, -2512, 215, -2992, -3690, + -4060, 2799, -2003, 4707, 3454, -4696, 3237, -4515, -2501, -4208, 4613, -2388, 3682, + -2017, 351, 1129, 2137, 33, 1600, -3136, -1317, -3143, 3968, -3290, -3032, -3292, + -2359, 2732, -2563, -3316, -2501, -2299, 4869, 3583, 4256, 4692, 2640, -2913, 12, + -1190, 820, -165, -3337, -4385, 897, 3677, -2226, -4866, 2553, 4533, 3878, -2714, 624, + -2266, 3075, 349, -4288, 1984, -4376, 2792, 1504, 3822, -945, 3913, -4538, -527, -4916, + -840, -3878, 1053, 4397, -3178, 4750, -3663, -1083, -994, -69, -2803, 2505, 4236, + -4643, 1599, 3290, -3102, -4015, -3553, -3916, -4408, 3725, 3996, 4855, -172, 338, + 2342, -572, 4795, -4258, -4963, 506, 1767, 53, 4793, 3505, -854, -1391, -1076, 4854, + 4465, -2761, 1206, -791, 492, 1499, 3175, -3964, -1939, -1353, 618, 13, 1727, 712, + 2896, -3091, 2841, -4870, 4090, 4034, 2915, 1286, -1477, -4334, -3656, -2264, -2963, + 416, 893, -3051, -4029, -4156, -2223, 4285, 1200, -410, -4715, 3325, 2118, 668, -4994, + 4729, -992, -459, -4775, 536, -3020, -4284, -4530, 384, 3747, -4672, 2936, 1204, -4300, + 2523, 1364, -3589, 1040, -4750, -3496, -1517, -3234, 1141, -2330, -4155, -4494, 4088, + -1744, 107, 3266, 857, -2322, -801, -2326, -845, 191, 3990, 4832, -4142, -4004, 3917, + 3290, -1033, -3293, 3234, 3246, -3538, 4402, 3239, -1574, 4095, -4094, 3314, -4650, + -414, 279, 2776, 822, 1879, -2699, 812, 676, -1836, 2357, -2430, 1038, -688, -4856, + 1561, 3180, 3200, -4357, -3144, 3061, -2353, 939, 4808, 4290, 2452, -4021, -2382, + -3581, -993, -2716, -453, 4977, 675, 3613, 3709, -1629, 3642, 1339, 1336, -2379, -3499, + 1034, 3129, -3642, -3564, 3469, -2103, 3504, -202, -798, -1895, -3762, 32, -4935, + -2484, -519, 579, 4023, -3273, -3229, -3687, -4618, 1140, -184, 3488, 319, 589, 513, + 3259, -4149, -2729, -1717, -636, 2038, -1988, -1816, -3241, -1499, 4574, 3733, 59, + 2714, 2649, 1595, 3522, -459, -4584, 377, -3948, -4435, 4891, -4862, -1690, -4033, 55, + -1213, 2224, 3222, 1439, 2441, 1648, 1804, 2834, 4368, -3559, 3872, -2332, 4974, 4176, + 137, -4367, -1759, 745, 3018, -3985, -2026, 4252, -4154, 3956, 524, 1966, 581, 3144, + -2760, 4334, 296, -3124, 27, -3795, -2982, -709, -3359, -1535, 1191, -2529, 1259, + -1300, -4783, -2984, -3057, -376, 2064, -3495, -3843, -3498, 2666, 4275, -2954, 2632, + 4789, 1046, -2855, 1003, -1848, -3099, 3326, 4153, -3816, 4649, -4650, -4595, -654, + -3975, 3970, -664, -205, 4793, -3677, 532, 3856, 896, -1790, 2776, 692, -450, 290, + -1205, -1148, 2350, 3315, -4964, 4361, -1240, 4984, 3729, -2466, 1050, 3082, 1806, + -3064, 584, -4210, -3383, 4182, 4066, -1884, 1388, 4425, -1899, 610, 1450, 4982, 3621, + 193, 2038, 1754, -407, -105, -4720, 638, 167, 2420, -655, 1883, -1135, -304, -4167, + -4610, -2368, -4811, 2839, -4817, -1183, -2871, 1753, -4321, 3613, -4400, 3252, 145, + 4861, -2849, 3318, 3963, 2813, -93, 4554, -3524, -4383, -3789, 429, -2736, 966, 4531, + 4942, -4302, 4522, -3845, 2587, 257, -1842, -536, -1238, 3510, -4054, -3935, 3380, + -1835, 946, -1460, 2297, 3042, -536, -1806, -2416, -4730, -2285, -2800, -3794, -2894, + -3698, -304, 3833, 2611, 4067, -4585, 1645, -4825, 1354, -1552, -81, -1921, 2988, 1321, + 2592, -3403, -2803, -1491, 3652, -4929, -4342, -878, 1859, 2997, -4001, -3101, -880, + -3680, -2964, 1984, -88, -3085, -1047, 4485, -4259, -4801, -3433, -792, 1844, -4831, + 4681, -121, -3892, 2207, 259, 706, -1151, -925, 3026, -4876, 2607, 2774, -2116, -4872, + -454, -1855, -4519, -3286, -4851, -832, -1662, -4693, 1793, -1496, -3895, -3303, 3217, + 955, 1641, -2657, 1133, -2903, -4321, -4264, 4555, 633, -3046, -4070, -4748, 4904, + -4721, -2512, -130, -3246, 1072, -2824, 1701, 415, 3086, -769, 2480, 4975, -4740, + -4486, 3938, 1657, -10, 4438, 3981, 447, 242, -382, 1070, 631, -939, 2219, 3781, -4010, + -2167, 3672, -3437, -3698, -4498, 1928, -4279, -102, -3553, -4055, 3406, -2778, 3686, + 794, -1423, -2156, 3683, -3453, -1760, -4515, 1464, -3277, -4663, 1653, 2168, 3130, + 255, -3534, -142, -2488, 4656, -1682, -1799, -4858, -3724, -3494, -2298, -4316, 23, + -4730, 1312, 3250, -1525, -4689, 1850, 4195, 488, -3480, 1101, -4817, -202, 2892, 3848, + 1784, -4755, -2813, -538, 3343, 3258, 1859, 3871, -984, 3172, -2168, -559, 2683, 1088, + -2985, -1024, 3516, 3298, -4961, -3717, -1795, 4997, 4146, 769, -1325, -4083, 4387, 20, + 1030, 2442, -3265, -2611, -4627, -1520, -2927, -4223, -4214, 3381, -3215, -4478, 3345, + -4021, 1085, 713, -4065, 4735, -4117, -2814, 1096, -4352, -2915, -248, -4479, 4260, + -3018, 1636, 2688, 4919, 2236, 1792, 2065, 4278, -802, -3504, 1386, -3989, -4024, 2547, + -2879, -1798, 2245, 1702, 3564, -3461, -2428, -2743, -2630, -3080, -3346, 4359, -3920, + 2298, -1609, -1040, -4490, 4591, 867, -2967, -3325, -2864, -4501, 2775, 790, -624, + -3744, -4728, -4297, 86, -4033, 4515, -1458, -1505, -1434, 3456, -814, 3437, 4198, + -2374, 3364, -3915, -3335, 3908, -4660, -3640, -2186, -3846, 3012, 4752, -1662, 3706, + -2475, -4370, 4249, -1821, -1921, 3313, 3838, -2483, 3421, -855, 991, -3031, -3161, + -692, 1565, -1238, 4473, -1319, -3030, -1853, 2053, -2292, 1508, 1715, -571, -3934, + 2689, -337, -3229, 541, 1259, 3631, -1428, -2486, -4034, 988, 3170, 3168, -2801, -4345, + -1150, -1556, -2064, 1278, 4406, 4427, -4687, 2523, -2629, -1673, 2073, -1539, -2827, + 4934, -3898, 587, -3583, -3537, 1153, 1126, -4405, -3505, 4213, -2594, 2370, -1141, + -1695, -2504, -167, -777, -148, 2879, -4481, 1126, 2793, -3415, -3535, -3629, 444, + 2107, 2271, -913, 3099, 1519, 3596, 715, 2552, -2508, -247, 3257, 2590, -41, -1643, + -4114, 2809, 865, 686, -2981, -4741, -2687, -2565, -3972, -899, -4532, -2131, -4544, + 1731, 2578, 1074, -3605, -4157, -3726, -1684, 24, -4489, 3585, 722, 3971, -4943, -905, + 3174, 38, -2817, 1658, 2295, 722, 1983, 1231, 4503, -2768, -700, 590, -3520, 2408, 505, + -2298, -2142, 4818, -4443, 561, -880, 28, -1344, 713, -1668, -1908, 2182, 1467, -3680, + 2358, -3926, -1013, 4094, -17, -3636, 2264, 4714, 1746, -610, -4575, 1255, -1837, + -3533, 792, -769, -2381, -2120, -282, 1128, 4948, -280, 4079, -2909, -1234, 2587, 808, + -2874, -175, -3841, 2518, -1780, -4965, -3686, 456, -853, 4156, -4866, -1640, -4249, + 1208, -3522, -2706, -2411, 2524, 2976, 4694, -910, -4811, 4372, 2419, -4699, -3298, + -156, -4477, 1539, -4391, -3173, 1637, 3186, 2416, -3173, 169, 2623, -101, -2486, + -4585, -1356, 436, -1331, -4622, -3324, 2858, 2952, 4846, 2137, 915, -2012, -384, 2288, + -2618, 3074, -4667, -1085, -3944, 656, -4938, 4616, -476, -2871, 2442, -3016, -128, + 2049, -1604, 3026, 3582, -4798, 3775, 416, -4335, -448, 3759, -2245, -3583, -2156, + -1446, 4443, 1824, -3001, 3422, -4879, 733, -3587, 4917, 793, -3127, -2940, -3825, + 4074, 985, -2499, -3378, -1792, 2395, -3974, 1720, 1291, -3012, -4071, 4072, -4023, + -4807, -4992, -2746, -4078, -4124, 137, -4184, -1197, -3910, 2912, -2711, 2253, 4979, + 2299, -2678, -2098, 2602, 1369, -4346, -2271, 4734, -2562, -2726, 226, 1463, 3134, + -2028, -652, 1453, 4503, -2693, 518, 3333, 2437, -4305, -1821, -4339, -1856, 2659, + -4039, -3093, 1576, -1528, -4355, -1408, -2028, -4372, -804, 1811, 535, 835, -3771, + -1284, -1468, -44, 1158, 4749, -380, -1704, 4724, -1880, -474, 1406, 3983, -1555, + -4426, -3309, 1588, -4462, -4336, 3104, -4123, -4647, -2058, 2004, -4377, -148, 625, + 2611, 2842, 3724, -3851, -4865, -1410, -4854, 2328, -1145, 2804, -3259, 1909, 4381, + -2221, 4102, -4917, -4308, -4468, 2312, 1099, 1161, -3953, -2595, 290, 2569, 4959, + -2372, -2861, -3772, 2580, -2529, -3222, 2440, 3456, -2852, 4444, -255, 1125, 2210, + -302, 616, -3820, -185, 1064, 1226, 4472, 2479, 4593, -2518, -1995, 3536, 333, -3895, + 2587, -4268, 638, -3835, -3936, -482, 3399, 32, 2508, -1104, -1562, -1022, -2362, 3245, + -941, -831, -4256, 2362, -231, -3951, 1518, 1467, -4442, -2857, -1939, 603, 4190, + -2814, -3774, -1397, 2004, -3700, -3232, -4577, -3653, 396, -434, 230, -3335, 1152, + -3000, -1383, 4173, -4214, -4332, -3403, -3421, 1224, 2728, 1260, -2842, -1575, -1733, + 4312, -4266, -4548, 169, 4562, -3430, 3211, 4235, 1890, -3289, -2936, -250, 3960, 2545, + -233, -3246, -4213, 3217, -435, 4942, -2912, -4727, -2185, 2579, -4163, 4388, 4269, + -3114, -1170, -4191, -360, 2321, 3319, 4881, -3374, -1980, -3589, -4546, 893, -3016, + -2643, -2001, -4664, 3829, 950, -3543, -2595, -4635, -2666, -4951, 4094, 3592, -3730, + -4881, -1983, 4313, 253, 1117, -23, 4160, -3495, -4847, -409, 1562, -1424, -146, -4928, + -3866, -1984, 50, 4193, -3055, -3148, -4253, -2479, 3061, 1344, -4741, 3366, -2115, + -561, -2282, 4107, 268, -1446, -2950, 2432, -1201, -2980, 1735, -3902, -2208, -1084, + 1182, 4029, 316, -1941, -1242, -417, -2601, -3865, 3357, -4930, 271, -2658, 2780, + -1123, -4594, 3295, 2686, -2597, 3252, 718, -1965, 2285, 3428, 1678, 960, -4899, -4051, + -2636, 1385, 2626, 2157, -2263, -159, 3938, -3407, 2096, -3967, -507, 4768, 2873, 4935, + 4109, -4904, -4619, -3439, 739, 584, 923, 3499, 1731, -3151, 442, 3606, 1850, 3287, + 1040, -2231, 4223, -3412, 1467, -2917, -1600, -3842, 606, 1938, 4463, -4080, 3366, 758, + 4685, 4023, -4771, 4298, 4356, 470, -1825, -804, -3317, 4988, 2619, -2054, -2810, 3275, + -2531, 519, -659, 1197 + ]) + ); +} + +struct Solution; + +impl Solution { + pub fn find_length_of_lcis(nums: Vec) -> i32 { + let len = nums.len(); + let mut max = 0; // 最大值 + let mut incr = 1; // 增长的最大值,当出现减小的时候,置为1 + + for (index, &value) in nums.iter().enumerate() { + if index + 1 < len && value < nums[index + 1] { + incr += 1; + continue; + } + + if incr > max { + max = incr; + if max as usize > nums.len() - index { + break; + } + } + incr = 1; + } + + max + } +} diff --git a/src/bin/longest-even-odd-subarray-with-threshold.rs b/src/bin/longest-even-odd-subarray-with-threshold.rs new file mode 100644 index 00000000..a6ae4724 --- /dev/null +++ b/src/bin/longest-even-odd-subarray-with-threshold.rs @@ -0,0 +1,37 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn longest_alternating_subarray(nums: Vec, threshold: i32) -> i32 { + let mut result = 0; + let mut index = 0; + let mut left_index = nums.len(); + while index < nums.len() { + if nums[index] > threshold { + index += 1; + left_index = nums.len(); + continue; + } + + if left_index == nums.len() { + if nums[index] % 2 == 0 { + left_index = index; + result = result.max(1); + } + index += 1; + } else { + if nums[index - 1] % 2 != nums[index] % 2 && nums[index] <= threshold { + result = result.max(index - left_index + 1); + index += 1; + } else { + left_index = nums.len(); + } + } + } + + result as i32 + } +} diff --git a/src/bin/longest-harmonious-subsequence.rs b/src/bin/longest-harmonious-subsequence.rs new file mode 100644 index 00000000..5a875df2 --- /dev/null +++ b/src/bin/longest-harmonious-subsequence.rs @@ -0,0 +1,49 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn find_lhs(nums: Vec) -> i32 { + let mut hash = std::collections::HashMap::::new(); + + for &i in nums.iter() { + hash.entry(i).and_modify(|x| *x += 1).or_insert(1); + } + + let mut res = 0; + + for &i in nums.iter() { + let s = hash.get(&(i - 1)); + let s1 = hash.get(&i).unwrap(); + if s.is_some() { + if s1 + *s.unwrap() > res { + res = s1 - *s.unwrap(); + } + } + } + + res + } + + pub fn find_lhs1(nums: Vec) -> i32 { + let mut hash = std::collections::HashMap::::new(); + let mut res = 0; + for &i in nums.iter() { + hash.entry(i).and_modify(|x| *x += 1).or_insert(1); + + let s = hash.get(&(i - 1)); + if s.is_some() && res < hash.get(&i).unwrap() + s.unwrap() { + res = hash.get(&i).unwrap() + s.unwrap() + } + + let s = hash.get(&(i + 1)); + if s.is_some() && res < hash.get(&i).unwrap() + s.unwrap() { + res = hash.get(&i).unwrap() + s.unwrap() + } + } + + res + } +} diff --git a/src/bin/longest-increasing-subsequence.rs b/src/bin/longest-increasing-subsequence.rs new file mode 100644 index 00000000..c346f25d --- /dev/null +++ b/src/bin/longest-increasing-subsequence.rs @@ -0,0 +1,74 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + println!( + "{}", + Solution::length_of_lis(vec![10, 9, 2, 5, 3, 7, 101, 18]) + ); + println!("{}", Solution::length_of_lis(vec![0, 1, 0, 3, 2, 3])); + println!("{}", Solution::length_of_lis(vec![7, 7, 7, 7, 7, 7, 7])); + + println!( + "{}", + Solution::length_of_lis1(vec![10, 9, 2, 5, 3, 7, 101, 18]) + ); + println!("{}", Solution::length_of_lis1(vec![0, 1, 0, 3, 2, 3])); + println!("{}", Solution::length_of_lis1(vec![7, 7, 7, 7, 7, 7, 7])); +} + +struct Solution; + +impl Solution { + /// 动态规划 + /// dp[i] = max(dp[j] + 1, dp[i]), 0 <= j <= i && nums[j] < nums[i] + pub fn length_of_lis(nums: Vec) -> i32 { + let mut v = vec![1; nums.len()]; + + for i in 1..nums.len() { + for j in 0..i { + if nums[j] < nums[i] { + v[i] = v[i].max(v[j] + 1); + } + } + } + + v.into_iter().fold(0, |x, y| x.max(y)) + } + + /// 动态规划 + 二分查找 + /// 比如序列是78912345,前三个遍历完以后tail是789, + /// 这时候遍历到1,就得把1放到合适的位置, + /// 于是在tail二分查找1的位置,变成了189(如果序列在此时结束,因为res不变,所以依旧输出3), + /// 再遍历到2成为129,然后是123直到12345 + /// + /// 很具小巧思。新建数组 cell,用于保存最长上升子序列。 + /// 对原序列进行遍历,将每位元素二分插入 cell 中。 + /// 如果 cell 中元素都比它小,将它插到最后 + /// 否则,用它覆盖掉比它大的元素中最小的那个。 + /// 总之,思想就是让 cell 中存储比较小的元素。这样,cell 未必是真实的最长上升子序列,但长度是对的。 + pub fn length_of_lis1(nums: Vec) -> i32 { + let mut v = vec![nums[0]]; + + for &num in &nums[1..] { + if num > v[v.len() - 1] { + v.push(num); + continue; + } + + let (mut i, mut j) = (0, v.len() - 1); + + while i < j { + let middle = (i + j) / 2; + if v[middle] < num { + i = middle + 1; + } else { + j = middle; + } + } + + v[i] = num; + } + + v.len() as i32 + } +} diff --git a/src/bin/longest-palindrome.rs b/src/bin/longest-palindrome.rs new file mode 100644 index 00000000..c5200c82 --- /dev/null +++ b/src/bin/longest-palindrome.rs @@ -0,0 +1,33 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn longest_palindrome(s: String) -> i32 { + let mut hash = std::collections::HashMap::new(); + s.as_bytes().into_iter().for_each(|x| { + hash.entry(x).and_modify(|v| *v += 1).or_insert(1); + }); + + let mut odd = false; // 是否有单数,如果有单数的话,则最后的结果+1 + + let mut r = 0; + + hash.into_iter().for_each(|(_, v)| { + if v % 2 == 0 { + r += v; + } else { + odd = true; + r += v - 1; + } + }); + + if odd { + r + 1 + } else { + r + } + } +} diff --git a/src/bin/longest-palindromic-subsequence.rs b/src/bin/longest-palindromic-subsequence.rs new file mode 100644 index 00000000..31e68062 --- /dev/null +++ b/src/bin/longest-palindromic-subsequence.rs @@ -0,0 +1,49 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn longest_palindrome_subseq(s: String) -> i32 { + let mut dp = vec![]; + for i in 0..s.len() { + dp.push(vec![-1; s.len()]); + } + + Self::dfs(s.as_bytes(), &mut dp, 0, s.len() - 1); + + dp[0][s.len() - 1] + } + + pub fn dfs(s: &[u8], v: &mut [Vec], i: usize, j: usize) { + if v[i][j] != -1 { + return; + } + + if i == j { + v[i][j] = 1; + return; + } + + if i > j { + v[i][j] = 0; + return; + } + + if j == 0 || i == s.len() - 1 { + v[i][j] = 0; + return; + } + + if s[i] == s[j] { + Self::dfs(s, v, i + 1, j - 1); + v[i][j] = v[i + 1][j - 1] + 2; + } else { + Self::dfs(s, v, i + 1, j); + Self::dfs(s, v, i, j - 1); + + v[i][j] = v[i + 1][j].max(v[i][j - 1]); + } + } +} diff --git a/src/bin/longest-palindromic-substring.rs b/src/bin/longest-palindromic-substring.rs new file mode 100644 index 00000000..88afbd58 --- /dev/null +++ b/src/bin/longest-palindromic-substring.rs @@ -0,0 +1,51 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +use std::f32::consts::E; + +fn main() { + assert_eq!( + Solution::longest_palindrome("aaaa".into()), + "aaaa".to_string() + ); +} + +struct Solution; + +impl Solution { + pub fn longest_palindrome(s: String) -> String { + let length = s.len(); + if length == 1 { + return s; + } + + let bytes = s.as_bytes(); + + let mut v: Vec> = (0..length) + .map(|x| (0..length).map(|y| x == y).collect::>()) + .collect(); + + let (mut start, mut end) = (0, 0); + + for i in 1..length { + for start1 in 0..length { + let end1 = start1 + i; + if end1 >= length { + break; + } + + if i == 1 { + v[start1][end1] = bytes[start1] == bytes[end1]; + } else { + v[start1][end1] = bytes[start1] == bytes[end1] && v[start1 + 1][end1 - 1]; + } + + if end1 - start1 >= end - start { + start = start1; + end = end1; + } + } + } + + s[start..=end].to_owned() + } +} diff --git a/src/bin/longest-substring-without-repeating-characters.rs b/src/bin/longest-substring-without-repeating-characters.rs new file mode 100644 index 00000000..fbc394f4 --- /dev/null +++ b/src/bin/longest-substring-without-repeating-characters.rs @@ -0,0 +1,42 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + assert_eq!(2, Solution::length_of_longest_substring("aab".to_string())); + assert_eq!( + 3, + Solution::length_of_longest_substring("abcabcbb".to_string()) + ); + assert_eq!(2, Solution::length_of_longest_substring("au".to_string())); + assert_eq!( + 5, + Solution::length_of_longest_substring("tmmzuxt".to_string()) + ); + assert_eq!(1, Solution::length_of_longest_substring(" ".to_string())); + assert_eq!(3, Solution::length_of_longest_substring("dvdf".to_string())); +} + +struct Solution; + +impl Solution { + pub fn length_of_longest_substring(s: String) -> i32 { + if s.len() == 1 { + return 1; + } + + let (mut max, mut slow) = (0, 0); + let mut hash = std::collections::HashMap::new(); + + for (index, value) in s.as_bytes().into_iter().enumerate() { + if let Some(&v) = hash.get(value) { + if v >= slow { + slow = v + 1; + } + } + + hash.insert(*value, index); + max = max.max(index - slow + 1); + } + + max as i32 + } +} diff --git a/src/bin/longest-uncommon-subsequence-i.rs b/src/bin/longest-uncommon-subsequence-i.rs new file mode 100644 index 00000000..51ec4e5d --- /dev/null +++ b/src/bin/longest-uncommon-subsequence-i.rs @@ -0,0 +1,15 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn find_lu_slength(a: String, b: String) -> i32 { + if a == b { + -1 + } else { + (a.len().max(b.len())) as _ + } + } +} diff --git a/src/bin/longest-valid-parentheses.rs b/src/bin/longest-valid-parentheses.rs new file mode 100644 index 00000000..f79238b6 --- /dev/null +++ b/src/bin/longest-valid-parentheses.rs @@ -0,0 +1,111 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() { + for i in vec![ + ("(()", 2), + (")()())", 4), + ("", 0), + ("(()))())(", 4), + ("))))((()((", 2), + ("()()))))()()(", 4), + ] { + assert_eq!( + Solution::force_longest_valid_parentheses(i.0.into()), + i.1, + "{}", + i.0 + ); + assert_eq!( + Solution::longest_valid_parentheses(i.0.into()), + i.1, + "{}", + i.0 + ); + } +} + +struct Solution; + +impl Solution { + /// 暴力解法 + /// 从大到小开始求解 + pub fn force_longest_valid_parentheses(s: String) -> i32 { + let mut len = s.len() / 2 * 2; // 因为括号都是成对出现的,所以从最长的长度开始 + let b = s.as_bytes(); + + while len > 0 { + for i in 0..b.len() { + if i + len > b.len() { + break; + } + if b[i] == b')' { + continue; + } + + if b[i + len - 1] != b')' { + continue; + } + + let mut left_num = 0; // 左括号的数量 + let mut invalid = false; + for j in i..i + len { + match b[j] { + b'(' => left_num += 1, + b')' => { + // 出现右括号但是左括号的数量为0时,说明不满足条件 + if left_num == 0 { + invalid = true; + break; + } + + left_num -= 1; + } + _ => unreachable!(), + } + } + + if !invalid && left_num == 0 { + return len as i32; + } + } + len -= 2; + } + + 0 + } + + /// 使用dp + pub fn longest_valid_parentheses(s: String) -> i32 { + // dp[i] = 2+dp[i-1] + dp[i-dp[i-1]-2] + // 2+dp[i-1]是内部的 + // dp[i-dp[i-1]-2]是与之相连的外部的 + let mut dp = vec![0; s.len()]; + let mut b = s.as_bytes(); + let mut ans = 0; + for i in 0..b.len() { + match b[i] { + b')' => { + if i < 1 { + continue; + } + + let inner = dp[i - 1]; + if i > inner { + if b[i - inner - 1] == b'(' { + dp[i] += inner + 2; + + if i > inner + 2 { + dp[i] += dp[i - inner - 2]; + } + } + } + + ans = ans.max(dp[i] as i32); + } + _ => continue, + } + } + + ans + } +} diff --git a/src/bin/longest-word-lcci.rs b/src/bin/longest-word-lcci.rs new file mode 100644 index 00000000..e85f2ad6 --- /dev/null +++ b/src/bin/longest-word-lcci.rs @@ -0,0 +1,46 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn longest_word(mut words: Vec) -> String { + words.sort_by(|x, y| { + if x.len() == y.len() { + x.cmp(y) + } else { + y.len().cmp(&x.len()) + } + }); + + let mut set = words + .iter() + .map(|x| x.as_bytes()) + .collect::>(); + + for i in words.iter() { + set.remove(i.as_bytes()); + if Self::check(&set, i.as_bytes()) { + return i.into(); + } + set.insert(i.as_bytes()); + } + + "".into() + } + + fn check(set: &std::collections::HashSet<&[u8]>, s: &[u8]) -> bool { + if s.is_empty() || set.contains(s) { + return true; + } + + for i in 0..s.len() { + if set.contains(&s[..i]) && Self::check(set, &s[i..]) { + return true; + } + } + + false + } +} diff --git a/src/bin/lowest-common-ancestor-of-a-binary-search-tree.rs b/src/bin/lowest-common-ancestor-of-a-binary-search-tree.rs new file mode 100644 index 00000000..7cf5b89a --- /dev/null +++ b/src/bin/lowest-common-ancestor-of-a-binary-search-tree.rs @@ -0,0 +1,53 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +// Definition for a binary tree node. +#[derive(Debug, PartialEq, Eq)] +pub struct TreeNode { + pub val: i32, + pub left: Option>>, + pub right: Option>>, +} + +impl TreeNode { + #[inline] + pub fn new(val: i32) -> Self { + TreeNode { + val, + left: None, + right: None, + } + } +} + +use std::cell::RefCell; +use std::rc::Rc; + +impl Solution { + /// 1.搜索二叉树 + /// 2.节点值唯一 + pub fn lowest_common_ancestor( + root: Option>>, + p: Option>>, + q: Option>>, + ) -> Option>> { + if root.is_none() { + return None; + } + + let val = root.as_ref().unwrap().borrow().val; + let left = p.as_ref().unwrap().borrow().val; + let right = q.as_ref().unwrap().borrow().val; + + if (left <= val && right >= val) || (right <= val && left >= val) { + root + } else if left < val && right < val { + Self::lowest_common_ancestor(root.as_ref().unwrap().borrow_mut().left.take(), p, q) + } else { + Self::lowest_common_ancestor(root.as_ref().unwrap().borrow_mut().right.take(), p, q) + } + } +} diff --git a/src/bin/lowest-common-ancestor-of-a-binary-tree.rs b/src/bin/lowest-common-ancestor-of-a-binary-tree.rs new file mode 100644 index 00000000..6fff9510 --- /dev/null +++ b/src/bin/lowest-common-ancestor-of-a-binary-tree.rs @@ -0,0 +1,59 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +// Definition for a binary tree node. +#[derive(Debug, PartialEq, Eq)] +pub struct TreeNode { + pub val: i32, + pub left: Option>>, + pub right: Option>>, +} + +impl TreeNode { + #[inline] + pub fn new(val: i32) -> Self { + TreeNode { + val, + left: None, + right: None, + } + } +} +use std::cell::RefCell; +use std::rc::Rc; +impl Solution { + /// 递归搜寻,当root为空或者root为p或者q就返回root + /// 然后搜寻子树,如果返回的都不为空,说明root是父节点 + pub fn lowest_common_ancestor( + mut root: Option>>, + mut p: Option>>, + mut q: Option>>, + ) -> Option>> { + if root.is_none() || root == p || root == q { + return root; + } + + let left = Self::lowest_common_ancestor( + root.clone().and_then(|x| x.borrow_mut().left.take()), + p.clone(), + q.clone(), + ); + + let right = Self::lowest_common_ancestor( + root.clone().and_then(|x| x.borrow_mut().right.take()), + p.clone(), + q.clone(), + ); + + if left.is_none() { + right + } else if right.is_none() { + left + } else { + root + } + } +} diff --git a/src/bin/lowest-common-ancestor-of-deepest-leaves.rs b/src/bin/lowest-common-ancestor-of-deepest-leaves.rs new file mode 100644 index 00000000..50ea2fe7 --- /dev/null +++ b/src/bin/lowest-common-ancestor-of-deepest-leaves.rs @@ -0,0 +1,50 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +// Definition for a binary tree node. +#[derive(Debug, PartialEq, Eq)] +pub struct TreeNode { + pub val: i32, + pub left: Option>>, + pub right: Option>>, +} + +impl TreeNode { + #[inline] + pub fn new(val: i32) -> Self { + TreeNode { + val, + left: None, + right: None, + } + } +} +use std::cell::RefCell; +use std::rc::Rc; +impl Solution { + pub fn lca_deepest_leaves( + root: Option>>, + ) -> Option>> { + let (s, _) = Self::f(root); + s + } + + pub fn f(r: Option>>) -> (Option>>, i32) { + if r.is_none() { + return (r, 0); + } + let (s1, h1) = Self::f(r.as_ref().unwrap().borrow().left.clone()); + let (s2, h2) = Self::f(r.as_ref().unwrap().borrow().right.clone()); + + if h1 == h2 { + (r, h1 + 1) + } else if h1 < h2 { + (s2, h2 + 1) + } else { + (s1, h1 + 1) + } + } +} diff --git a/src/bin/lru-cache.rs b/src/bin/lru-cache.rs new file mode 100644 index 00000000..6a61b2a0 --- /dev/null +++ b/src/bin/lru-cache.rs @@ -0,0 +1,204 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +use std::{ + cell::RefCell, + rc::{Rc, Weak}, +}; + +fn main() { + // ["LRUCache","put","put","put","put","get","get","get","get","put","get","get","get","get","get"] + // [[3], [1,1],[2,2],[3,3],[4,4],[4], [3], [2], [1], [5,5], [1], [2], [3], [4], [5]] + // [null, null, null, null, null, 4, 3, 2, -1, null, -1, 2, 3, -1, 5] + + let mut lru = LRUCache::new(3); + lru.put(1, 1); + lru.put(2, 2); + lru.put(3, 3); + lru.put(4, 4); + + assert_eq!(lru.get(4), 4); + assert_eq!(lru.get(3), 3); + assert_eq!(lru.get(2), 2); + assert_eq!(lru.get(1), -1); + + lru.put(5, 5); + + assert_eq!(lru.get(1), -1); + assert_eq!(lru.get(2), 2); + assert_eq!(lru.get(3), 3); + assert_eq!(lru.get(4), -1); + assert_eq!(lru.get(5), 5); +} + +struct Solution; + +#[derive(Clone)] +struct KeyValuePair { + key: i32, + value: i32, +} + +struct LRUCache { + map: std::collections::HashMap>>, + list: List, + capacity: usize, +} + +struct Node { + value: KeyValuePair, + next: Option>>, + prev: Option>>, +} + +struct List { + length: usize, + head: Option>>, + tail: Option>>, +} + +impl List { + fn new() -> Self { + Self { + length: 0, + head: None, + tail: None, + } + } + + // 从链表中移除当前节点 + // 当前节点的prev节点的next节点指向当前节点的next节点 + // 当前节点的next节点的prev节点指向当前节点的prev节点 + fn remove(&mut self, node: Rc>) { + if self.length == 0 { + return; + } + + self.length -= 1; + + let prev = node.borrow_mut().prev.take(); + let next = node.borrow_mut().next.take(); + + // 说明移除的是头节点, head要指向next节点 + if prev.is_none() { + self.head = next.clone(); + } + + // 说明移除的尾节点,tail要指向prev节点 + if next.is_none() { + self.tail = prev.clone(); + } + + prev.clone().map(|x| x.borrow_mut().next = next.clone()); + next.clone().map(|x| x.borrow_mut().prev = prev.clone()); + } + + /// 向列表头部插入数据 + /// head指向新的数据 + /// 新数据的next指向原列表头部 + fn push_front(&mut self, value: KeyValuePair) -> Rc> { + self.length += 1; + + let node = Rc::new(RefCell::new(Node { + value, + next: None, + prev: None, + })); + + // 获取当前头头节点 + let head = self.head.take(); + + // 新的头节点的下一个元素指向旧的头节点 + node.borrow_mut().next = head.clone(); + + // 旧的头节点的prev指向新的头节点 + head.clone() + .map(|x| x.borrow_mut().prev = Some(node.clone())); + + // 如果长度为1,尾节点和头节点指向头一个节点 + if self.length == 1 { + self.tail = Some(node.clone()); + } + + self.head = Some(node.clone()); + + node + } + + /// 移除尾部元素 + /// 获取到tail的值, + /// 将tail.prev设置为tail + /// tail.prev.next设置为None + /// 返回最后节点的key + fn pop(&mut self) -> Option { + match self.tail.take() { + None => None, + Some(node) => { + self.length -= 1; + let prev = node.borrow().prev.clone(); + prev.clone().map(|x| x.borrow_mut().next = None); + self.tail = prev.clone(); // 将tail节点设置为 prev + node.borrow_mut().prev = None; + + if self.length == 0 { + self.head = None; + } + + Some(node.borrow().value.key) + } + } + } +} + +impl Drop for List { + fn drop(&mut self) { + // 回收所有节点 + while let Some(_) = self.pop() {} + } +} + +impl LRUCache { + fn new(capacity: i32) -> Self { + Self { + capacity: capacity as usize, + map: Default::default(), + list: List::new(), + } + } + + fn get(&mut self, key: i32) -> i32 { + match self._get(key) { + None => -1, + Some(x) => x.borrow().value.value, + } + } + + fn _get(&mut self, key: i32) -> Option>> { + match self.map.get_mut(&key) { + None => None, + Some(x) => { + self.list.remove(x.clone()); // 先移除当前节点 + let new = self.list.push_front(x.borrow().value.clone()); // 新插入节点 + *x = new.clone(); + Some(new) + } + } + } + + fn put(&mut self, key: i32, value: i32) { + match self._get(key) { + None => { + if self.map.len() == self.capacity { + if let Some(x) = self.list.pop() { + self.map.remove(&x); + } + } + + let x = self.list.push_front(KeyValuePair { key, value }); + self.map.insert(key, x); + } + Some(x) => { + x.borrow_mut().value.value = value; + } + } + } +} diff --git a/src/bin/lwyVBB.rs b/src/bin/lwyVBB.rs new file mode 100644 index 00000000..dfe4ca2f --- /dev/null +++ b/src/bin/lwyVBB.rs @@ -0,0 +1,40 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn is_alien_sorted(words: Vec, order: String) -> bool { + let mut dict = [0; 26]; + for (i, &v) in order.as_bytes().into_iter().enumerate() { + dict[(v - b'a') as usize] = i + } + + for i in 1..words.len() { + let mut index = 0; + loop { + match ( + words[i - 1].as_bytes().get(index), + words[i].as_bytes().get(index), + ) { + (Some(&x), Some(&y)) => { + if dict[(x - b'a') as usize] > dict[(y - b'a') as usize] { + return false; + } else if dict[(x - b'a') as usize] < dict[(y - b'a') as usize] { + break; + } + } + (Some(&x), None) => return false, + _ => { + break; + } + } + + index += 1; + } + } + + true + } +} diff --git a/src/bin/magic-index-lcci.rs b/src/bin/magic-index-lcci.rs new file mode 100644 index 00000000..105f26fa --- /dev/null +++ b/src/bin/magic-index-lcci.rs @@ -0,0 +1,17 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn find_magic_index(nums: Vec) -> i32 { + for i in 0..nums.len() { + if nums[i] as usize == i { + return nums[i]; + } + } + + -1 + } +} diff --git a/src/bin/magical-string.rs b/src/bin/magical-string.rs new file mode 100644 index 00000000..1b86193f --- /dev/null +++ b/src/bin/magical-string.rs @@ -0,0 +1,44 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn magical_string(n: i32) -> i32 { + if n == 0 { + return 0; + } + + let mut s = vec![1, 2, 2]; + let mut p = 2usize; + + while s.len() <= n as usize { + if s[p] == 1 { + if s[s.len() - 1] == 1 { + s.push(2) + } else { + s.push(1) + } + } else { + if s[s.len() - 1] == 1 { + s.push(2); + s.push(2); + } else { + s.push(1); + s.push(1); + } + } + p += 1; + } + + let mut count = 0; + + for i in 0..n as usize { + if s[i] == 1 { + count += 1; + } + } + count + } +} diff --git a/src/bin/majority-element-ii.rs b/src/bin/majority-element-ii.rs index 9eadda21..dc27b2ca 100644 --- a/src/bin/majority-element-ii.rs +++ b/src/bin/majority-element-ii.rs @@ -1,3 +1,5 @@ +#![allow(dead_code, unused, unused_variables)] + fn main() { let s = vec![3, 2, 3, 2, 2, 3, 1, 1, 1]; println!("{:?}", Solution::majority_element1(s)); @@ -14,10 +16,17 @@ impl Solution { let mut m = std::collections::HashMap::new(); for &i in nums.iter() { - m.entry(i).and_modify(|e| { (*e) += 1; }).or_insert(1); + m.entry(i) + .and_modify(|e| { + (*e) += 1; + }) + .or_insert(1); } - m.iter().filter(|(&x, &y)| y > length).map(|(&x, &y)| x).collect() + m.iter() + .filter(|(&_x, &y)| y > length) + .map(|(&x, &_y)| x) + .collect() } // 摩尔投票法 @@ -86,9 +95,9 @@ impl Solution { } } - v.iter(). - enumerate(). - map(|(x, &y)| { + v.iter() + .enumerate() + .map(|(x, &y)| { if x == 0 && index_0_num > nums.len() / 3 { return y; } @@ -97,8 +106,9 @@ impl Solution { return y; } None - }). - filter(|x| x.is_some()). - map(|mut x| x.unwrap()).collect() + }) + .filter(|x| x.is_some()) + .map(|x| x.unwrap()) + .collect() } } diff --git a/src/bin/majority-element.rs b/src/bin/majority-element.rs new file mode 100644 index 00000000..20362dd1 --- /dev/null +++ b/src/bin/majority-element.rs @@ -0,0 +1,28 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn majority_element(nums: Vec) -> i32 { + let mut m = std::collections::HashMap::new(); + + for i in nums.iter() { + if let Some(x) = m.get_mut(i) { + if *x + 1 > nums.len() / 2 { + return *i; + } else { + *x += 1; + } + } else { + if 1 > nums.len() / 2 { + return *i; + } + m.insert(i, 1usize); + } + } + + -1 + } +} diff --git a/src/bin/make-costs-of-paths-equal-in-a-binary-tree.rs b/src/bin/make-costs-of-paths-equal-in-a-binary-tree.rs new file mode 100644 index 00000000..b8c7beb0 --- /dev/null +++ b/src/bin/make-costs-of-paths-equal-in-a-binary-tree.rs @@ -0,0 +1,31 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() { + assert_eq!(Solution::min_increments(7, vec![1, 5, 2, 2, 3, 3, 1]), 6); + assert_eq!(Solution::min_increments(3, vec![5, 3, 3]), 0); + assert_eq!( + Solution::min_increments( + 15, + vec![ + 764, 1460, 2664, 764, 2725, 4556, 5305, 8829, 5064, 5929, 7660, 6321, 4830, 7055, + 3761, + ], + ), + 15735 + ); +} + +struct Solution; + +impl Solution { + pub fn min_increments(n: i32, cost: Vec) -> i32 { + let mut cost = cost; + let mut ans = 0; + for i in (1..=n as usize / 2).rev() { + // 从最后一个非叶节点开始算 + ans += (cost[i * 2 - 1] - cost[i * 2]).abs(); // 两个子节点变成一样的 + cost[i - 1] += cost[i * 2 - 1].max(cost[i * 2]); // 累加路径和 + } + ans + } +} diff --git a/src/bin/make-the-string-great.rs b/src/bin/make-the-string-great.rs new file mode 100644 index 00000000..d7e64f1a --- /dev/null +++ b/src/bin/make-the-string-great.rs @@ -0,0 +1,25 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn make_good(s: String) -> String { + let mut v = vec![]; + for &i in s.as_bytes() { + if v.is_empty() { + v.push(i); + } else { + let &m = v.last().unwrap(); + if (m > i && m - i == 32) || (m < i && i - m == 32) { + v.pop(); + } else { + v.push(i); + } + } + } + + String::from_utf8(v).unwrap() + } +} diff --git a/src/bin/make-three-strings-equal.rs b/src/bin/make-three-strings-equal.rs new file mode 100644 index 00000000..88895ef6 --- /dev/null +++ b/src/bin/make-three-strings-equal.rs @@ -0,0 +1,31 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn find_minimum_operations(s1: String, s2: String, s3: String) -> i32 { + let mut a = 0; + let mut index = 0; + loop { + match ( + s1.as_bytes().get(index), + s2.as_bytes().get(index), + s3.as_bytes().get(index), + ) { + (Some(&x1), Some(&x2), Some(&x3)) if x1 == x2 && x2 == x3 => { + a += 1; + index += 1; + } + _ => break, + } + } + + if a == 0 { + -1 + } else { + (s1.len() - a + s2.len() - a + s3.len() - a) as _ + } + } +} diff --git a/src/bin/master-mind-lcci.rs b/src/bin/master-mind-lcci.rs new file mode 100644 index 00000000..edc56225 --- /dev/null +++ b/src/bin/master-mind-lcci.rs @@ -0,0 +1,58 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn master_mind(solution: String, guess: String) -> Vec { + let mut v = vec![0; 4]; + for &i in solution.as_bytes() { + match i { + b'R' => v[0] += 1, + b'Y' => v[1] += 1, + b'G' => v[2] += 1, + b'B' => v[3] += 1, + _ => {} + } + } + let mut right1 = 0; + let mut right2 = 0; + + for i in 0..4 { + if solution.as_bytes()[i] == guess.as_bytes()[i] { + right1 += 1; + } + + match guess.as_bytes()[i] { + b'R' => { + if v[0] > 0 { + v[0] -= 1; + right2 += 1; + } + } + b'Y' => { + if v[1] > 0 { + v[1] -= 1; + right2 += 1; + } + } + b'G' => { + if v[2] > 0 { + v[2] -= 1; + right2 += 1; + } + } + b'B' => { + if v[3] > 0 { + v[3] -= 1; + right2 += 1; + } + } + _ => {} + } + } + + vec![right1, right2 - right1] + } +} diff --git a/src/bin/matrix-diagonal-sum.rs b/src/bin/matrix-diagonal-sum.rs new file mode 100644 index 00000000..61036e3f --- /dev/null +++ b/src/bin/matrix-diagonal-sum.rs @@ -0,0 +1,22 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn diagonal_sum(mat: Vec>) -> i32 { + let (mut i, mut j, mut sum) = (0, mat.len() - 1, 0); + + while i < j { + sum += mat[i][i]; + sum += mat[i][j]; + sum += mat[j][i]; + sum += mat[j][j]; + i += 1; + j -= 1; + } + sum += (mat[i][i] * (mat.len() as i32 & 1)); + sum + } +} diff --git a/src/bin/max-consecutive-ones-iii.rs b/src/bin/max-consecutive-ones-iii.rs new file mode 100644 index 00000000..a2730f9e --- /dev/null +++ b/src/bin/max-consecutive-ones-iii.rs @@ -0,0 +1,50 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + assert_eq!( + 6, + Solution::longest_ones(vec![1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0], 2) + ); + assert_eq!( + 10, + Solution::longest_ones( + vec![0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1], + 3 + ) + ); +} + +struct Solution; + +impl Solution { + pub fn longest_ones(a: Vec, mut k: i32) -> i32 { + let (mut slow, mut fast, mut count) = (0, 0, 0); + while fast < a.len() { + if k > 0 { + if a[fast] == 0 { + k -= 1; + } + fast += 1; + } else { + if a[fast] == 1 { + fast += 1; + } else { + if a[slow] == 0 { + fast += 1 + } + slow += 1; + } + } + + if fast < slow { + fast = slow; + } + + if fast - slow > count { + count = fast - slow; + } + } + + count as i32 + } +} diff --git a/src/bin/max-consecutive-ones.rs b/src/bin/max-consecutive-ones.rs new file mode 100644 index 00000000..1c182cde --- /dev/null +++ b/src/bin/max-consecutive-ones.rs @@ -0,0 +1,22 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn find_max_consecutive_ones(nums: Vec) -> i32 { + let mut r = 0; + let mut count = 0; + + for i in nums { + if i == 1 { + count += 1; + } else { + r = r.max(count); + count = 0 + } + } + r + } +} diff --git a/src/bin/max-increase-to-keep-city-skyline.rs b/src/bin/max-increase-to-keep-city-skyline.rs new file mode 100644 index 00000000..69739792 --- /dev/null +++ b/src/bin/max-increase-to-keep-city-skyline.rs @@ -0,0 +1,38 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn max_increase_keeping_skyline(grid: Vec>) -> i32 { + // v[0]为从数组竖直方向(即顶部,底部)看 + // v[1]为从数组水平方向(即顶部,底部)看 + let mut v = vec![vec![0; grid[0].len()]; 2]; + // sum1 增加后的总和 + // sum2 增加前的总和 + let (mut sum1, mut sum2) = (0, 0); + + for i in 0..grid.len() { + for j in 0..grid[0].len() { + if grid[i][j] > v[0][j] { + v[0][j] = grid[i][j]; + } + + if grid[i][j] > v[1][i] { + v[1][i] = grid[i][j]; + } + sum2 += grid[i][j]; + } + } + + // 新的二维数组的节点值为天际线数组对应值的最小值 + for i in 0..grid.len() { + for j in 0..grid[0].len() { + sum1 += v[0][j].min(v[1][i]); + } + } + + sum1 - sum2 + } +} diff --git a/src/bin/max-sum-of-a-pair-with-equal-sum-of-digits.rs b/src/bin/max-sum-of-a-pair-with-equal-sum-of-digits.rs new file mode 100644 index 00000000..85bebde3 --- /dev/null +++ b/src/bin/max-sum-of-a-pair-with-equal-sum-of-digits.rs @@ -0,0 +1,37 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn maximum_sum(nums: Vec) -> i32 { + let mut hash = std::collections::HashMap::new(); + let mut result = -1; + for i in nums { + let s = Self::sum(i); + if !hash.contains_key(&s) { + hash.insert(s, i); + continue; + } + + let old = hash[&s]; + result = result.max(old + i); + if old < i { + hash.insert(s, i); + } + } + + result + } + + pub fn sum(mut num: i32) -> i32 { + let mut sum = 0; + while num > 0 { + sum += num % 10; + num /= 10; + } + + sum + } +} diff --git a/src/bin/maximal-rectangle.rs b/src/bin/maximal-rectangle.rs new file mode 100644 index 00000000..d49997bb --- /dev/null +++ b/src/bin/maximal-rectangle.rs @@ -0,0 +1,51 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn maximal_rectangle(matrix: Vec>) -> i32 { + // 构造柱状图 + let mut v = vec![vec![]; matrix.len()]; + + for i in 0..matrix.len() { + v[i].push(0); + for j in 0..matrix[0].len() { + if matrix[i][j] == '0' { + v[i].push(0); + } else { + let value = if i == 0 { 1 } else { v[i - 1][j + 1] + 1 }; + v[i].push(value); + } + } + + v[i].push(0); + } + + let mut ans = 0; + + for v1 in v { + let len = v1.len(); + let mut stack = vec![]; + + for v2 in 0..len { + while !stack.is_empty() && v1[stack[stack.len() - 1]] >= v1[v2] { + let top = stack.pop().unwrap(); + ans = ans.max(v1[top] * (v2 - *stack.last().unwrap_or(&0) - 1) as i32); + } + + stack.push(v2); + } + + let last = *stack.last().unwrap_or(&0); + + while !stack.is_empty() { + let top = stack.pop().unwrap(); + ans = ans.max(v1[top] * (last - *stack.last().unwrap_or(&0)) as i32); + } + } + + ans + } +} diff --git a/src/bin/maximal-score-after-applying-k-operations.rs b/src/bin/maximal-score-after-applying-k-operations.rs new file mode 100644 index 00000000..133770da --- /dev/null +++ b/src/bin/maximal-score-after-applying-k-operations.rs @@ -0,0 +1,29 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +use std::collections::BinaryHeap; + +fn main() {} + +struct Solution; + +impl Solution { + pub fn max_kelements(nums: Vec, k: i32) -> i64 { + use std::collections::BinaryHeap; + let mut heap: BinaryHeap = nums.into_iter().collect(); + + let mut r = 0; + for i in 0..k { + let x = heap.pop().unwrap(); + r += x as i64; + heap.push({ + if (x / 3) * 3 == x { + x / 3 + } else { + x / 3 + 1 + } + }); + } + + r + } +} diff --git a/src/bin/maximize-distance-to-closest-person.rs b/src/bin/maximize-distance-to-closest-person.rs new file mode 100644 index 00000000..f379d510 --- /dev/null +++ b/src/bin/maximize-distance-to-closest-person.rs @@ -0,0 +1,29 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn max_dist_to_closest(seats: Vec) -> i32 { + let mut s = 0; + let mut last = -1; + + for i in 0..seats.len() { + if seats[i] == 1 { + if last == -1 { + s = s.max(i as i32); + } else { + s = s.max((i as i32 - last) / 2); + } + last = i as i32; + } + } + + if seats[seats.len() - 1] == 0 { + s = s.max(seats.len() as i32 - 1 - last); + } + + s + } +} diff --git a/src/bin/maximize-number-of-subsequences-in-a-string.rs b/src/bin/maximize-number-of-subsequences-in-a-string.rs new file mode 100644 index 00000000..d6919e2b --- /dev/null +++ b/src/bin/maximize-number-of-subsequences-in-a-string.rs @@ -0,0 +1,31 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn maximum_subsequence_count(text: String, pattern: String) -> i64 { + let mut pattern = pattern.bytes(); + let a = pattern.next().unwrap(); + let b = pattern.next().unwrap(); + + let mut count = [0; 2]; + + let mut result = 0; + + for i in text.bytes() { + if i == a { + count[0] += 1; + } else if i == b { + result += count[0]; + count[1] += 1; + } + } + if a != b { + result + count[0].max(count[1]) + } else { + count[0] * (count[0] + 1) / 2 + } + } +} diff --git a/src/bin/maximum-absolute-sum-of-any-subarray.rs b/src/bin/maximum-absolute-sum-of-any-subarray.rs new file mode 100644 index 00000000..7e4b98b5 --- /dev/null +++ b/src/bin/maximum-absolute-sum-of-any-subarray.rs @@ -0,0 +1,25 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn max_absolute_sum(nums: Vec) -> i32 { + let mut r = 0; + let (mut max, mut min) = (0, 0); // max表示正数前缀和,min表示负数前缀和 + for i in nums { + r = r.max(max + i).max((min + i).abs()).max(i.abs()); + + if i > 0 { + max += i; + min = 0.min(i + min); + } else if i < 0 { + min += i; + max = 0.max(max + i); + } + } + + r + } +} diff --git a/src/bin/maximum-alternating-subsequence-sum.rs b/src/bin/maximum-alternating-subsequence-sum.rs new file mode 100644 index 00000000..8157b86a --- /dev/null +++ b/src/bin/maximum-alternating-subsequence-sum.rs @@ -0,0 +1,21 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + /// dp[i]表示前i个元素子序列的最大值 + /// 则 dp[i]的值可能为奇数或者偶数 + pub fn max_alternating_sum(nums: Vec) -> i64 { + // odd奇数,even 偶数 + let (mut odd, mut even, mut result) = (0, nums[0] as i64, nums[0] as i64); + + for &i in nums[1..].into_iter() { + even = even.max(odd - i as i64); + odd = odd.max(even + i as i64); + result = odd.max(even); + } + result + } +} diff --git a/src/bin/maximum-area-of-a-piece-of-cake-after-horizontal-and-vertical-cuts.rs b/src/bin/maximum-area-of-a-piece-of-cake-after-horizontal-and-vertical-cuts.rs new file mode 100644 index 00000000..b0794323 --- /dev/null +++ b/src/bin/maximum-area-of-a-piece-of-cake-after-horizontal-and-vertical-cuts.rs @@ -0,0 +1,35 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn max_area( + h: i32, + w: i32, + mut horizontal_cuts: Vec, + mut vertical_cuts: Vec, + ) -> i32 { + horizontal_cuts.sort_unstable(); + vertical_cuts.sort_unstable(); + let mut r = 0; + + let horizontal_max = Self::get_max(h, horizontal_cuts); + let vertical_max = Self::get_max(w, vertical_cuts); + + ((horizontal_max as i64) * (vertical_max as i64) % (10i64.pow(9) + 7)) as i32 + } + + fn get_max(s: i32, cuts: Vec) -> i32 { + let mut max = cuts[0].max(s - cuts[cuts.len() - 1]); + + if cuts.len() > 1 { + for i in 1..cuts.len() { + max = max.max(cuts[i] - cuts[i - 1]); + } + } + + max + } +} diff --git a/src/bin/maximum-ascending-subarray-sum.rs b/src/bin/maximum-ascending-subarray-sum.rs new file mode 100644 index 00000000..5b50c914 --- /dev/null +++ b/src/bin/maximum-ascending-subarray-sum.rs @@ -0,0 +1,22 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn max_ascending_sum(nums: Vec) -> i32 { + let mut result = nums[0]; + let mut n = nums[0]; + for i in 1..nums.len() { + if nums[i] > nums[i - 1] { + n += nums[i]; + } else { + n = nums[i]; + } + result = result.max(n); + } + + result + } +} diff --git a/src/bin/maximum-average-subarray-i.rs b/src/bin/maximum-average-subarray-i.rs new file mode 100644 index 00000000..08f5e9a4 --- /dev/null +++ b/src/bin/maximum-average-subarray-i.rs @@ -0,0 +1,20 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn find_max_average(nums: Vec, k: i32) -> f64 { + let k = k as usize; + let mut sum = nums[0..k].iter().sum::(); + let mut argv = (sum as f64) / (k as f64); + + for i in k..nums.len() { + sum = sum + nums[i] - nums[i - k]; + argv = argv.max((sum as f64) / (k as f64)); + } + + argv + } +} diff --git a/src/bin/maximum-count-of-positive-integer-and-negative-integer.rs b/src/bin/maximum-count-of-positive-integer-and-negative-integer.rs new file mode 100644 index 00000000..383b5925 --- /dev/null +++ b/src/bin/maximum-count-of-positive-integer-and-negative-integer.rs @@ -0,0 +1,17 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() { + assert_eq!(Solution::maximum_count(vec![-2, -1, -1, 1, 2, 3]), 3); + assert_eq!(Solution::maximum_count(vec![-3, -2, -1, 0, 0, 1, 2]), 3); + assert_eq!(Solution::maximum_count(vec![5, 20, 66, 1314]), 4); +} + +struct Solution; + +impl Solution { + pub fn maximum_count(nums: Vec) -> i32 { + let mut index1 = nums.partition_point(|x| *x < 0); + let mut index2 = nums.partition_point(|x| *x < 1); + (index1 as i32).max((nums.len() - index2) as i32) + } +} diff --git a/src/bin/maximum-depth-of-binary-tree.rs b/src/bin/maximum-depth-of-binary-tree.rs new file mode 100644 index 00000000..c080fa06 --- /dev/null +++ b/src/bin/maximum-depth-of-binary-tree.rs @@ -0,0 +1,46 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +// Definition for a binary tree node. +#[derive(Debug, PartialEq, Eq)] +pub struct TreeNode { + pub val: i32, + pub left: Option>>, + pub right: Option>>, +} + +impl TreeNode { + #[inline] + pub fn new(val: i32) -> Self { + TreeNode { + val, + left: None, + right: None, + } + } +} + +use std::cell::RefCell; +use std::rc::Rc; + +impl Solution { + pub fn max_depth(root: Option>>) -> i32 { + if root.is_none() { + return 0; + } + + let root = root.unwrap(); + + let left = 1 + Self::max_depth(Rc::clone(&root).borrow_mut().left.take()); + let right = 1 + Self::max_depth(Rc::clone(&root).borrow_mut().right.take()); + + if left > right { + left + } else { + right + } + } +} diff --git a/src/bin/maximum-difference-between-node-and-ancestor.rs b/src/bin/maximum-difference-between-node-and-ancestor.rs new file mode 100644 index 00000000..a581b7eb --- /dev/null +++ b/src/bin/maximum-difference-between-node-and-ancestor.rs @@ -0,0 +1,56 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +use std::cell::RefCell; +use std::rc::Rc; + +fn main() {} + +struct Solution; + +// Definition for a binary tree node. +#[derive(Debug, PartialEq, Eq)] +pub struct TreeNode { + pub val: i32, + pub left: Option>>, + pub right: Option>>, +} + +impl TreeNode { + #[inline] + pub fn new(val: i32) -> Self { + TreeNode { + val, + left: None, + right: None, + } + } +} + +impl Solution { + pub fn max_ancestor_diff(root: Option>>) -> i32 { + let root = root.unwrap(); + let root_val = root.borrow().val; + let left = root.borrow_mut().left.take(); + let right = root.borrow_mut().right.take(); + Self::dfs(left, root_val, root_val).max(Self::dfs(right, root_val, root_val)) + } + + pub fn dfs(root: Option>>, max_parent: i32, min_parent: i32) -> i32 { + if root.is_none() { + return 0; + } + + let root = root.unwrap(); + let v = (max_parent - root.borrow().val) + .abs() + .max((min_parent - root.borrow().val).abs()); + + let max_parent = max_parent.max(root.borrow().val); + let min_parent = min_parent.min(root.borrow().val); + + let left = root.borrow_mut().left.take(); + let right = root.borrow_mut().right.take(); + + v.max(Self::dfs(left, max_parent, min_parent).max(Self::dfs(right, max_parent, min_parent))) + } +} diff --git a/src/bin/maximum-difference-by-remapping-a-digit.rs b/src/bin/maximum-difference-by-remapping-a-digit.rs new file mode 100644 index 00000000..5d0bf6aa --- /dev/null +++ b/src/bin/maximum-difference-by-remapping-a-digit.rs @@ -0,0 +1,53 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn min_max_difference(num: i32) -> i32 { + Self::max(num) - Self::min(num) + } + + fn max(mut num: i32) -> i32 { + let mut s = vec![]; + let mut first = 0; + while num > 0 { + let x = num % 10; + if x != 9 { + first = x; + } + s.push(x); + num /= 10; + } + + let mut n = 0; + while let Some(x) = s.pop() { + if x == first { + n = n * 10 + 9; + } else { + n = n * 10 + x; + } + } + n + } + + fn min(mut num: i32) -> i32 { + let mut s = vec![]; + while num > 0 { + s.push(num % 10); + num /= 10; + } + + let mut n = 0; + let mut first = s[s.len() - 1]; + while let Some(x) = s.pop() { + if x == first { + n = n * 10 + 0; + } else { + n = n * 10 + x; + } + } + n + } +} diff --git a/src/bin/maximum-enemy-forts-that-can-be-captured.rs b/src/bin/maximum-enemy-forts-that-can-be-captured.rs new file mode 100644 index 00000000..bf78ae33 --- /dev/null +++ b/src/bin/maximum-enemy-forts-that-can-be-captured.rs @@ -0,0 +1,28 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn capture_forts(forts: Vec) -> i32 { + let mut r = 0; + let mut x = 0; + let mut m = forts[0]; + for i in 1..forts.len() { + if forts[i] == 0 { + if m != 0 { + x += 1; + } + } else { + if m != forts[i] { + r = r.max(x); + } + x = 0; + m = forts[i]; + } + } + + r + } +} diff --git a/src/bin/maximum-gap.rs b/src/bin/maximum-gap.rs new file mode 100644 index 00000000..5a02c6e9 --- /dev/null +++ b/src/bin/maximum-gap.rs @@ -0,0 +1,19 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn maximum_gap(nums: Vec) -> i32 { + let mut heap: std::collections::BinaryHeap = nums.into_iter().collect(); + let mut r = 0; + let mut prev = heap.pop().unwrap(); + while let Some(x) = heap.pop() { + r = r.max(prev - x); + prev = x; + } + + r + } +} diff --git a/src/bin/maximum-good-subarray-sum.rs b/src/bin/maximum-good-subarray-sum.rs new file mode 100644 index 00000000..4938ed68 --- /dev/null +++ b/src/bin/maximum-good-subarray-sum.rs @@ -0,0 +1,37 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn maximum_subarray_sum(nums: Vec, k: i32) -> i64 { + let mut hash = std::collections::HashMap::new(); + let mut sum = 0i64; + let mut result = i64::MIN; + for x in nums { + if let Some(&s) = hash.get(&(x + k)) { + result = result.max(sum + x as i64 - s); + } + + if let Some(&s) = hash.get(&(x - k)) { + result = result.max(sum + x as i64 - s); + } + + match hash.get(&x) { + Some(&s) if s < sum => {} + _ => { + hash.insert(x, sum); + } + } + + sum += x as i64; + } + + if result == i64::MIN { + 0 + } else { + result + } + } +} diff --git a/src/bin/maximum-lcci.rs b/src/bin/maximum-lcci.rs new file mode 100644 index 00000000..0aab6ce8 --- /dev/null +++ b/src/bin/maximum-lcci.rs @@ -0,0 +1,19 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + assert_eq!(10, Solution::maximum(5, 10)); +} + +struct Solution; + +impl Solution { + pub fn maximum(a: i32, b: i32) -> i32 { + // 当a > b时,最高位为0 + // 当a < b时,a - b为负数,最高位为1 + // 因此求出最高为是0还是1 + let ret = ((a as i64 - b as i64) as u64 >> 63) as i32; + // 当最高位为1时,说明b>a,因此ret^1 == 0,所以下面表达式就为b * 1 + // 当最高位为0时,说明b 1,所以下边的表达式为1 * a + b * ret + (ret ^ 1) * a + } +} diff --git a/src/bin/maximum-length-of-repeated-subarray.rs b/src/bin/maximum-length-of-repeated-subarray.rs new file mode 100644 index 00000000..fdf0961e --- /dev/null +++ b/src/bin/maximum-length-of-repeated-subarray.rs @@ -0,0 +1,26 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn find_length(nums1: Vec, nums2: Vec) -> i32 { + let mut v = vec![vec![0; nums1.len()]; nums2.len()]; + let mut res = 0; + for (i, &v1) in nums1.iter().enumerate() { + for (j, &v2) in nums2.iter().enumerate() { + if v1 == v2 { + v[j][i] = if j != 0 && i != 0 { + v[j - 1][i - 1] + 1 + } else { + 1 + }; + } + res = res.max(v[j][i]) + } + } + + res + } +} diff --git a/src/bin/maximum-number-of-alloys.rs b/src/bin/maximum-number-of-alloys.rs new file mode 100644 index 00000000..c460daf4 --- /dev/null +++ b/src/bin/maximum-number-of-alloys.rs @@ -0,0 +1,53 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn max_number_of_alloys( + n: i32, + k: i32, + budget: i32, + composition: Vec>, + stock: Vec, + cost: Vec, + ) -> i32 { + (0..k as usize) + .map(|i| { + // 已有的能制造多少 + let mut x = (0..n as usize) + .map(|x| stock[x] / composition[i][x]) + .min() + .unwrap(); + + let mut total_cost = 0; // 购买的总消费 + loop { + let mut p = 0; + + for m in 0..n as usize as usize { + // 表示剩下已有的不够造了,因此需要去买 + if stock[m] - x * composition[i][m] <= 0 { + p += composition[i][m] * cost[m]; + } else { + if stock[m] - x * composition[i][m] < composition[i][m] { + p += (composition[i][m] - stock[m] + x * composition[i][m]) + * cost[m]; + } + } + } + + if p + total_cost <= budget { + x += 1; + total_cost += p; + } else { + break; + } + } + + x + }) + .max() + .unwrap() + } +} diff --git a/src/bin/maximum-number-of-balloons.rs b/src/bin/maximum-number-of-balloons.rs new file mode 100644 index 00000000..7d43ee33 --- /dev/null +++ b/src/bin/maximum-number-of-balloons.rs @@ -0,0 +1,23 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn max_number_of_balloons(text: String) -> i32 { + let mut v = [0; 5]; + for i in text.bytes() { + match i { + b'b' => v[0] += 1, + b'a' => v[1] += 1, + b'l' => v[2] += 1, + b'o' => v[3] += 1, + b'n' => v[4] += 1, + _ => {} + } + } + + v[0].min(v[1]).min(v[2] / 2).min(v[3] / 2).min(v[4]) + } +} diff --git a/src/bin/maximum-number-of-balls-in-a-box.rs b/src/bin/maximum-number-of-balls-in-a-box.rs new file mode 100644 index 00000000..28d69a8a --- /dev/null +++ b/src/bin/maximum-number-of-balls-in-a-box.rs @@ -0,0 +1,26 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn count_balls(low_limit: i32, high_limit: i32) -> i32 { + let mut max_num = 0; + let mut hash = std::collections::HashMap::new(); + for mut i in low_limit..=high_limit { + let mut sum = 0; + while i > 0 { + sum += i % 10; + i /= 10; + } + + let x = hash.entry(sum).and_modify(|x| *x += 1).or_insert(1); + if *x > max_num { + max_num = *x; + } + } + + max_num + } +} diff --git a/src/bin/maximum-number-of-moves-in-a-grid.rs b/src/bin/maximum-number-of-moves-in-a-grid.rs new file mode 100644 index 00000000..9a736d20 --- /dev/null +++ b/src/bin/maximum-number-of-moves-in-a-grid.rs @@ -0,0 +1,32 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn max_moves(grid: Vec>) -> i32 { + let mut dp = vec![0; grid.len()]; + + for i in (0..grid[0].len() - 1).rev() { + let mut new_dp = vec![0; grid.len()]; + for j in (0..grid.len()) { + if grid[j][i] < grid[j][i + 1] { + new_dp[j] = dp[j] + 1; + } + + if j != 0 && grid[j][i] < grid[j - 1][i + 1] { + new_dp[j] = new_dp[j].max(dp[j - 1] + 1) + } + + if j != grid.len() - 1 && grid[j][i] < grid[j + 1][i + 1] { + new_dp[j] = new_dp[j].max(dp[j + 1] + 1) + } + } + + dp = new_dp; + } + + dp.into_iter().max().unwrap() + } +} diff --git a/src/bin/maximum-number-of-operations-with-the-same-score-i.rs b/src/bin/maximum-number-of-operations-with-the-same-score-i.rs new file mode 100644 index 00000000..d3c4eb27 --- /dev/null +++ b/src/bin/maximum-number-of-operations-with-the-same-score-i.rs @@ -0,0 +1,24 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn max_operations(nums: Vec) -> i32 { + let mut result = 0; + let mut n = &nums[..]; + let mut sum = None; + while n.len() >= 2 { + match sum { + None => sum = Some(n[0] + n[1]), + Some(x) if n[0] + n[1] != x => break, + _ => {} + } + result += 1; + n = &n[2..]; + } + + result + } +} diff --git a/src/bin/maximum-number-of-vowels-in-a-substring-of-given-length.rs b/src/bin/maximum-number-of-vowels-in-a-substring-of-given-length.rs new file mode 100644 index 00000000..ebdbc5bb --- /dev/null +++ b/src/bin/maximum-number-of-vowels-in-a-substring-of-given-length.rs @@ -0,0 +1,45 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + assert_eq!( + 7, + Solution::max_vowels("ibpbhixfiouhdljnjfflpapptrxgcomvnb".to_string(), 33) + ); +} + +struct Solution; + +impl Solution { + pub fn max_vowels(s: String, k: i32) -> i32 { + let (mut slow, mut fast) = (0usize, 0usize); + let s = s.as_bytes(); + + if s.len() < k as usize { + return 0; + } + + let (mut count, mut max) = (0, 0); + while fast < s.len() { + if fast - slow > (k - 1) as usize { + slow += 1; + match s[slow - 1] { + b'a' | b'e' | b'i' | b'o' | b'u' => count -= 1, + _ => (), + } + } + + match s[fast] { + b'a' | b'e' | b'i' | b'o' | b'u' => count += 1, + _ => (), + } + + if count > max { + max = count; + } + + fast += 1; + } + + max + } +} diff --git a/src/bin/maximum-number-of-weeks-for-which-you-can-work.rs b/src/bin/maximum-number-of-weeks-for-which-you-can-work.rs new file mode 100644 index 00000000..090ff531 --- /dev/null +++ b/src/bin/maximum-number-of-weeks-for-which-you-can-work.rs @@ -0,0 +1,17 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn number_of_weeks(milestones: Vec) -> i64 { + let s = milestones.iter().map(|&x| x as i64).sum(); + let m = *milestones.iter().max().unwrap() as i64; + if m > s - m + 1 { + (s - m) * 2 + 1 + } else { + s + } + } +} diff --git a/src/bin/maximum-number-of-words-you-can-type.rs b/src/bin/maximum-number-of-words-you-can-type.rs new file mode 100644 index 00000000..4d695259 --- /dev/null +++ b/src/bin/maximum-number-of-words-you-can-type.rs @@ -0,0 +1,27 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn can_be_typed_words(text: String, broken_letters: String) -> i32 { + let mut s = [0; 26]; + for &i in broken_letters.as_bytes() { + s[(i - b'a') as usize] = 1; + } + + let mut res = 0; + 'l: for i in text.split(' ') { + for &j in i.as_bytes() { + if s[(j - b'a') as usize] == 1 { + continue 'l; + } + } + + res += 1; + } + + res + } +} diff --git a/src/bin/maximum-odd-binary-number.rs b/src/bin/maximum-odd-binary-number.rs new file mode 100644 index 00000000..ef41dea1 --- /dev/null +++ b/src/bin/maximum-odd-binary-number.rs @@ -0,0 +1,32 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() { + assert_eq!( + Solution::maximum_odd_binary_number("0101".to_string()), + "1001".to_string() + ); + + assert_eq!( + Solution::maximum_odd_binary_number("010".to_string()), + "001".to_string() + ); +} + +struct Solution; + +impl Solution { + pub fn maximum_odd_binary_number(s: String) -> String { + let mut l = s.len(); + let m = s.bytes().into_iter().filter(|x| *x == b'1').count(); + let mut s = String::with_capacity(l); + for i in 0..l - 1 { + if i < m - 1 { + s.push('1'); + } else { + s.push('0'); + } + } + s.push('1'); + s + } +} diff --git a/src/bin/maximum-of-absolute-value-expression.rs b/src/bin/maximum-of-absolute-value-expression.rs new file mode 100644 index 00000000..e27e8be7 --- /dev/null +++ b/src/bin/maximum-of-absolute-value-expression.rs @@ -0,0 +1,39 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + /// 将绝对值去掉 + /// |arr1[i] - arr1[j]| + |arr2[i] - arr2[j]| + |i - j| + // + // = (arr1[i] + arr2[i] + i) - (arr1[j] + arr2[j] + j) + // = (arr1[i] + arr2[i] - i) - (arr1[j] + arr2[j] - j) + // = (arr1[i] - arr2[i] + i) - (arr1[j] - arr2[j] + j) + // = (arr1[i] - arr2[i] - i) - (arr1[j] - arr2[j] - j) + pub fn max_abs_val_expr(arr1: Vec, arr2: Vec) -> i32 { + let (mut a_max, mut b_max, mut c_max, mut d_max) = (i32::MIN, i32::MIN, i32::MIN, i32::MIN); + let (mut a_min, mut b_min, mut c_min, mut d_min) = (i32::MAX, i32::MAX, i32::MAX, i32::MAX); + + for i in 0..arr1.len() { + let (x, y) = (arr1[i], arr2[i]); + a_max = a_max.max(x + y + i as i32); + a_min = a_min.min(x + y + i as i32); + + b_max = b_max.max(x + y - i as i32); + b_min = b_min.min(x + y - i as i32); + + c_max = c_max.max(x - y + i as i32); + c_min = c_min.min(x - y + i as i32); + + d_max = d_max.max(x - y - i as i32); + d_min = d_min.min(x - y - i as i32); + } + + (a_max - a_min) + .max(b_max - b_min) + .max(c_max - c_min) + .max(d_max - d_min) + } +} diff --git a/src/bin/maximum-points-you-can-obtain-from-cards.rs b/src/bin/maximum-points-you-can-obtain-from-cards.rs index 8a1d777d..6688a06d 100644 --- a/src/bin/maximum-points-you-can-obtain-from-cards.rs +++ b/src/bin/maximum-points-you-can-obtain-from-cards.rs @@ -1,5 +1,10 @@ +#![allow(dead_code, unused, unused_variables)] + fn main() { - assert_eq!(232, Solution::max_score1(vec![11, 49, 100, 20, 86, 29, 72], 4)); + assert_eq!( + 232, + Solution::max_score1(vec![11, 49, 100, 20, 86, 29, 72], 4) + ); } struct Solution; @@ -10,7 +15,7 @@ impl Solution { /// 如果从头开始的话,区间的和为card_points[..k]的和sum1,区间向后移动一位,区间sum1 = sum1+card_points[k]-card_points[0] pub fn max_score(card_points: Vec, k: i32) -> i32 { // 剩余数组的长度 - let other = (card_points.len() - k as usize); + let other = card_points.len() - k as usize; // 假设剩余数组从0下标开始,和为sum1 let mut sum1: i32 = card_points[0..other].iter().sum(); let mut sum = sum1; @@ -37,7 +42,8 @@ impl Solution { break; } - sum1 = sum1 - card_points[s - 1] + card_points[card_points.len() - (k as usize - s + 1)]; + sum1 = + sum1 - card_points[s - 1] + card_points[card_points.len() - (k as usize - s + 1)]; if sum1 > sum { sum = sum1; } @@ -47,4 +53,4 @@ impl Solution { sum } -} \ No newline at end of file +} diff --git a/src/bin/maximum-population-year.rs b/src/bin/maximum-population-year.rs new file mode 100644 index 00000000..9ff1032b --- /dev/null +++ b/src/bin/maximum-population-year.rs @@ -0,0 +1,25 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn maximum_population(logs: Vec>) -> i32 { + let mut v = vec![0; 1000]; + + for i in logs { + for x in (i[0] - 1950) as usize..(i[1] - 1950) as usize { + v[x] += 1; + } + } + + let mut max = 0; + + for i in 1..v.len() { + max = if v[i] > v[max] { i } else { max } + } + + max as i32 + 1950 + } +} diff --git a/src/bin/maximum-prime-difference.rs b/src/bin/maximum-prime-difference.rs new file mode 100644 index 00000000..18c6712a --- /dev/null +++ b/src/bin/maximum-prime-difference.rs @@ -0,0 +1,41 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +extern crate core; + +fn main() {} + +struct Solution; + +impl Solution { + pub fn maximum_prime_difference(nums: Vec) -> i32 { + let first = Self::prime(nums.iter()); + let last = nums.len() - 1 - Self::prime(nums.iter().rev()); + + (last - first) as i32 + } + + fn prime<'a, T: Iterator>(iter: T) -> usize { + fn is_prime(num: i32) -> bool { + if num == 1 { + return false; + } + + for i in 2..num / 2 + 1 { + if num % i == 0 { + return false; + } + } + + true + } + let mut i = 0; + for &v in iter { + if is_prime(v) { + return i; + } + i += 1; + } + + 0 + } +} diff --git a/src/bin/maximum-product-of-three-numbers.rs b/src/bin/maximum-product-of-three-numbers.rs new file mode 100644 index 00000000..e7952992 --- /dev/null +++ b/src/bin/maximum-product-of-three-numbers.rs @@ -0,0 +1,15 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn maximum_product(nums: Vec) -> i32 { + let mut nums = nums; + nums.sort(); + + (nums[0] * nums[1] * nums[nums.len() - 1]) + .max(nums[nums.len() - 1] * nums[nums.len() - 2] * nums[nums.len() - 3]) + } +} diff --git a/src/bin/maximum-product-of-word-lengths.rs b/src/bin/maximum-product-of-word-lengths.rs new file mode 100644 index 00000000..cca9bc4c --- /dev/null +++ b/src/bin/maximum-product-of-word-lengths.rs @@ -0,0 +1,29 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn max_product(words: Vec) -> i32 { + let mut v = vec![0i32; words.len()]; + + for i in 0..words.len() { + for &j in words[i].as_bytes() { + v[i] |= 1 << (j - b'a'); + } + } + + let mut r = 0; + + for i in 0..words.len() { + for j in i + 1..words.len() { + if (v[i] & v[j]) == 0 { + r = r.max(words[i].len() * words[j].len()) + } + } + } + + r as i32 + } +} diff --git a/src/bin/maximum-product-subarray.rs b/src/bin/maximum-product-subarray.rs new file mode 100644 index 00000000..a6d7774d --- /dev/null +++ b/src/bin/maximum-product-subarray.rs @@ -0,0 +1,45 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + assert_eq!(4, Solution::max_product(vec![3, -1, 4])); + assert_eq!(0, Solution::max_product(vec![-2, 0])); + assert_eq!(-2, Solution::max_product(vec![-2])); + assert_eq!(6, Solution::max_product(vec![2, 3, -2, 4])); + assert_eq!(0, Solution::max_product(vec![-2, 0, -1])); +} + +struct Solution; + +impl Solution { + pub fn max_product(nums: Vec) -> i32 { + let mut v = vec![0; nums.len()]; + v[0] = nums[0]; + + for i in 1..nums.len() { + if nums[i] != 0 { + v[i] = if v[i - 1] == 0 { + nums[i] + } else { + nums[i] * v[i - 1] + }; + } + } + + let mut result = v[0]; + let mut negative = 0; + + for i in v.into_iter() { + if i < 0 { + result = result.max(i / if negative == 0 { 1 } else { negative }); + negative = if negative == 0 { i } else { negative.max(i) }; + } else { + result = result.max(i); + if i == 0 { + negative = 0; + } + } + } + + result + } +} diff --git a/src/bin/maximum-repeating-substring.rs b/src/bin/maximum-repeating-substring.rs new file mode 100644 index 00000000..3746e87b --- /dev/null +++ b/src/bin/maximum-repeating-substring.rs @@ -0,0 +1,26 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn max_repeating(sequence: String, word: String) -> i32 { + let mut result = 0; + for i in 0..sequence.len() { + result = result.max(Self::d(&sequence[i..], &word)); + } + + result + } + + fn d(mut sequences: &str, word: &str) -> i32 { + let mut result = 0; + while sequences.len() >= word.len() && sequences.starts_with(word) { + result += 1; + sequences = &sequences[word.len()..]; + } + + result + } +} diff --git a/src/bin/maximum-rows-covered-by-columns.rs b/src/bin/maximum-rows-covered-by-columns.rs new file mode 100644 index 00000000..23552d60 --- /dev/null +++ b/src/bin/maximum-rows-covered-by-columns.rs @@ -0,0 +1,36 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn maximum_rows(matrix: Vec>, num_select: i32) -> i32 { + let mut v = vec![]; + for i in matrix.iter() { + let mut s = 0; + for j in 0..i.len() { + s |= i[j] << (i.len() - j - 1) as i32; + } + + v.push(s); + } + + let mut result = 0; + let mut s: i32 = (0..matrix[0].len()).fold(1, |x, y| x | (1 << y)); + + for i in 0..=s { + if i.count_ones() as i32 == num_select { + let mut r = 0; + for &v in v.iter() { + if v & i == v { + r += 1; + } + } + result = result.max(r); + } + } + + result + } +} diff --git a/src/bin/maximum-score-after-splitting-a-string.rs b/src/bin/maximum-score-after-splitting-a-string.rs new file mode 100644 index 00000000..76efae12 --- /dev/null +++ b/src/bin/maximum-score-after-splitting-a-string.rs @@ -0,0 +1,31 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn max_score(s: String) -> i32 { + let (mut score, mut left, mut right) = (0, 0, 0); + let s = s.as_bytes(); + + for i in 1..s.len() { + if s[i] == b'1' { + right += 1; + } + } + + for i in 0..s.len() - 1 { + if s[i] == b'0' { + left += 1; + } else if i != 0 && s[i] == b'1' { + right -= 1; + } + if left + right > score { + score = left + right; + } + } + + score + } +} diff --git a/src/bin/maximum-size-of-a-set-after-removals.rs b/src/bin/maximum-size-of-a-set-after-removals.rs new file mode 100644 index 00000000..f2bcbebf --- /dev/null +++ b/src/bin/maximum-size-of-a-set-after-removals.rs @@ -0,0 +1,30 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + /// 1. 先去重 + /// 2. 移除都存在的数 + pub fn maximum_set_size(nums1: Vec, nums2: Vec) -> i32 { + let l = nums1.len() as i32 / 2; + let n1 = nums1.into_iter().collect::>(); + let n2 = nums2.into_iter().collect::>(); + + let mut comm = n1.intersection(&n2).count() as i32; + let mut result = n1.len() as i32 + n2.len() as i32 - comm; // 所有元素的数量 + + if n1.len() as i32 > l { + let nm = comm.min(n1.len() as i32 - l); // 如果交集大于comm,则全部移除交集,否则,移除多余的n1的元素 + result -= n1.len() as i32 - nm - l; + comm -= nm; + } + + if n2.len() as i32 > l { + result -= (n2.len() as i32 - comm.min(n2.len() as i32 - l)) - l; + } + + result + } +} diff --git a/src/bin/maximum-split-of-positive-even-integers.rs b/src/bin/maximum-split-of-positive-even-integers.rs new file mode 100644 index 00000000..5ca1bf80 --- /dev/null +++ b/src/bin/maximum-split-of-positive-even-integers.rs @@ -0,0 +1,30 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn maximum_even_split(mut final_sum: i64) -> Vec { + let mut result = vec![]; + if final_sum % 2 == 1 { + return result; + } + + result.push(2); + + loop { + final_sum -= result[result.len() - 1]; + if final_sum <= result[result.len() - 1] { + let last = result[result.len() - 1]; + let len = result.len() - 1; + result[len] = last + final_sum; + break; + } else { + result.push(result[result.len() - 1] + 2); + } + } + + result + } +} diff --git a/src/bin/maximum-subarray.rs b/src/bin/maximum-subarray.rs new file mode 100644 index 00000000..203371ff --- /dev/null +++ b/src/bin/maximum-subarray.rs @@ -0,0 +1,25 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn max_sub_array(nums: Vec) -> i32 { + let mut sums = Vec::with_capacity(nums.len()); + sums.push(nums[0]); + + for i in 1..nums.len() { + sums.push(nums[i] + sums[i - 1]); + } + + let (mut min, mut sum) = (sums[0], sums[0]); + + for &i in sums.iter().skip(1) { + sum = sum.max(i.max(i - min)); + min = min.min(i); + } + + sum + } +} diff --git a/src/bin/maximum-sum-circular-subarray.rs b/src/bin/maximum-sum-circular-subarray.rs new file mode 100644 index 00000000..3af105cd --- /dev/null +++ b/src/bin/maximum-sum-circular-subarray.rs @@ -0,0 +1,48 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +use std::vec; + +fn main() {} + +struct Solution; + +impl Solution { + /// 取反,求最小和的连续子数组,则其余是最大和 + /// 两种情况:1.最大和子数组在数组中间 + /// 2.最大和子数组在数组两边,在数组两边就是最小和数组在中间 + pub fn max_subarray_sum_circular(mut nums: Vec) -> i32 { + let mut result = nums[0]; + let mut last = nums[0]; + + let mut all_positive = last < 0; // 是否全是负数, 如果全是负数的话,就不能探究第二种情况 + // 第一种情况 + for i in 1..nums.len() { + if last > 0 { + last += nums[i]; + } else { + last = nums[i]; + } + all_positive = all_positive && nums[i] < 0; + result = result.max(last); + } + + if all_positive { + return result; + } + + // 第二种情况 + let mut sum: i32 = nums.iter().map(|x| *x).sum(); + let mut last = nums[0]; + for i in 1..nums.len() { + if last > 0 { + last = nums[i]; + } else { + last += nums[i]; + } + + result = result.max(sum - last); + } + + result + } +} diff --git a/src/bin/maximum-sum-of-almost-unique-subarray.rs b/src/bin/maximum-sum-of-almost-unique-subarray.rs new file mode 100644 index 00000000..1134ee32 --- /dev/null +++ b/src/bin/maximum-sum-of-almost-unique-subarray.rs @@ -0,0 +1,42 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() { + assert_eq!(Solution::max_sum(vec![2, 6, 7, 3, 1, 7], 3, 4), 18); + assert_eq!(Solution::max_sum(vec![5, 9, 9, 2, 4, 5, 4], 1, 3), 23); + assert_eq!(Solution::max_sum(vec![1, 2, 1, 2, 1, 2, 1], 3, 3), 0); +} + +struct Solution; + +impl Solution { + pub fn max_sum(nums: Vec, m: i32, k: i32) -> i64 { + let mut hash = std::collections::HashMap::new(); + let mut result = 0; + let mut sum = 0; + for i in 0..nums.len() { + hash.entry(nums[i]).and_modify(|x| *x += 1).or_insert(1); + if i < k as usize { + sum += nums[i] as i64; + } else { + sum += (nums[i] - nums[i - k as usize]) as i64; + let c = if let Some(&x) = hash.get(&nums[i - k as usize]) { + x + } else { + -1 + }; + + if c == 1 { + hash.remove(&nums[i - k as usize]); + } else if c > 1 { + hash.insert(nums[i - k as usize], c - 1); + } + } + + if hash.len() >= m as usize { + result = result.max(sum); + } + } + + result + } +} diff --git a/src/bin/maximum-sum-with-exactly-k-elements.rs b/src/bin/maximum-sum-with-exactly-k-elements.rs new file mode 100644 index 00000000..cc9a4e42 --- /dev/null +++ b/src/bin/maximum-sum-with-exactly-k-elements.rs @@ -0,0 +1,12 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn maximize_sum(nums: Vec, k: i32) -> i32 { + let max = nums.into_iter().max().unwrap(); + max * k + (k - 1) * k / 2 + } +} diff --git a/src/bin/maximum-swap.rs b/src/bin/maximum-swap.rs new file mode 100644 index 00000000..1e94b6e7 --- /dev/null +++ b/src/bin/maximum-swap.rs @@ -0,0 +1,31 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn maximum_swap(num: i32) -> i32 { + let mut s: Vec = num.to_string().as_bytes().into_iter().map(|x| *x).collect(); + let n = s.len(); + let mut max_idx = n - 1; + let mut p = n; + let mut q = 0; + for i in (0..n - 1).rev() { + if s[i] > s[max_idx] { + // s[i] 是目前最大数字 + max_idx = i; + } else if s[i] < s[max_idx] { + // s[i] 右边有比它大的 + p = i; + q = max_idx; // 更新 p 和 q + } + } + if p == n { + // 这意味着 s 是降序的 + return num; + } + s.swap(p, q); // 交换 s[p] 和 s[q] + unsafe { String::from_utf8_unchecked(s) }.parse().unwrap() + } +} diff --git a/src/bin/maximum-units-on-a-truck.rs b/src/bin/maximum-units-on-a-truck.rs new file mode 100644 index 00000000..e8ab924d --- /dev/null +++ b/src/bin/maximum-units-on-a-truck.rs @@ -0,0 +1,35 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn maximum_units(box_types: Vec>, truck_size: i32) -> i32 { + let mut box_types = box_types; + box_types.sort_unstable_by(|x, y| { + use std::cmp::Ordering; + match x[1].cmp(&y[1]) { + Ordering::Equal => {} + x => return x.reverse(), + } + + x[0].cmp(&y[1]).reverse() + }); + + let mut r = 0; + let mut truck_size = truck_size; + + for box_type in box_types { + if box_type[0] >= truck_size { + r += truck_size * box_type[1]; + break; + } else { + r += box_type[0] * box_type[1]; + truck_size -= box_type[0]; + } + } + + r + } +} diff --git a/src/bin/maximum-value-after-insertion.rs b/src/bin/maximum-value-after-insertion.rs new file mode 100644 index 00000000..55bfe71e --- /dev/null +++ b/src/bin/maximum-value-after-insertion.rs @@ -0,0 +1,44 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn max_value(n: String, x: i32) -> String { + let mut r = Vec::with_capacity(n.len() + 1); + let mut n = n.as_bytes(); + let mut nega = false; + if n[0] == b'-' { + nega = true; + n = &n[1..]; + r.push(b'-'); + } + let x = x as u8 + b'0'; + let mut done = false; + for &i in n { + if done { + r.push(i); + } else { + if nega { + if x < i { + r.push(x); + done = true; + } + } else { + if x > i { + r.push(x); + done = true; + } + } + r.push(i); + } + } + + if !done { + r.push(x); + } + + unsafe { String::from_utf8_unchecked(r) } + } +} diff --git a/src/bin/maximum-value-at-a-given-index-in-a-bounded-array.rs b/src/bin/maximum-value-at-a-given-index-in-a-bounded-array.rs new file mode 100644 index 00000000..e0aecfda --- /dev/null +++ b/src/bin/maximum-value-at-a-given-index-in-a-bounded-array.rs @@ -0,0 +1,11 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn max_value(n: i32, index: i32, max_sum: i32) -> i32 { + (2 * max_sum - (n - index).pow(2) + n * index) / (4 - 2 * index) + } +} diff --git a/src/bin/maximum-value-of-a-string-in-an-array.rs b/src/bin/maximum-value-of-a-string-in-an-array.rs new file mode 100644 index 00000000..1aebb8eb --- /dev/null +++ b/src/bin/maximum-value-of-a-string-in-an-array.rs @@ -0,0 +1,14 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn maximum_value(strs: Vec) -> i32 { + strs.iter() + .map(|s| s.parse().unwrap_or(s.len() as i32)) + .max() + .unwrap() + } +} diff --git a/src/bin/maximum-value-of-an-ordered-triplet-ii.rs b/src/bin/maximum-value-of-an-ordered-triplet-ii.rs new file mode 100644 index 00000000..45e41af8 --- /dev/null +++ b/src/bin/maximum-value-of-an-ordered-triplet-ii.rs @@ -0,0 +1,22 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +use std::cmp::max; + +fn main() {} + +struct Solution; + +impl Solution { + pub fn maximum_triplet_value(nums: Vec) -> i64 { + let mut max_diff = 0; + let mut ans = 0; + let mut pre_max = 0; + for x in nums { + ans = ans.max(x as i64 * max_diff as i64); + max_diff = max_diff.max(pre_max - x); + pre_max = pre_max.max(x); + } + + ans + } +} diff --git a/src/bin/maximum-width-ramp.rs b/src/bin/maximum-width-ramp.rs new file mode 100644 index 00000000..86602aaa --- /dev/null +++ b/src/bin/maximum-width-ramp.rs @@ -0,0 +1,36 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + /// 单调递减栈 + /// 找出以0下标为起点的单调递减元素的下标,放到栈中 + /// 然后从后往前比较出最大值 + pub fn max_width_ramp(a: Vec) -> i32 { + let mut stack = vec![]; + for i in 0..a.len() { + if stack.is_empty() || a[i] <= a[*stack.last().unwrap()] { + stack.push(i); + } + } + + let mut result = 0; + + for i in (0..a.len()).rev() { + if stack.is_empty() { + break; + } + + while !stack.is_empty() && a[i] >= a[*stack.last().unwrap()] { + let r = i - stack.pop().unwrap(); + if r >= result { + result = r; + } + } + } + + result as i32 + } +} diff --git a/src/bin/maximum-xor-for-each-query.rs b/src/bin/maximum-xor-for-each-query.rs new file mode 100644 index 00000000..36585eee --- /dev/null +++ b/src/bin/maximum-xor-for-each-query.rs @@ -0,0 +1,20 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn get_maximum_xor(nums: Vec, maximum_bit: i32) -> Vec { + let mut r = vec![0; nums.len()]; + let max = (1 << maximum_bit) - 1; + let len = r.len(); + let mut current = 0; + for (i, v) in nums.into_iter().enumerate() { + current ^= v; + r[len - 1 - i] = (!current) & max; + } + + r + } +} diff --git a/src/bin/mean-of-array-after-removing-some-elements.rs b/src/bin/mean-of-array-after-removing-some-elements.rs new file mode 100644 index 00000000..b118a9f4 --- /dev/null +++ b/src/bin/mean-of-array-after-removing-some-elements.rs @@ -0,0 +1,18 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn trim_mean(mut arr: Vec) -> f64 { + arr.sort(); + + let f = arr[(arr.len() as f64 * 0.05) as usize..(arr.len() as f64 * 0.95) as usize] + .iter() + .sum::() as f64 + / (arr.len() as f64 * 0.9); + + f + } +} diff --git a/src/bin/median-of-two-sorted-arrays.rs b/src/bin/median-of-two-sorted-arrays.rs new file mode 100644 index 00000000..600f8e26 --- /dev/null +++ b/src/bin/median-of-two-sorted-arrays.rs @@ -0,0 +1,47 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +/// 如果两个数组的长度之和为奇数时,则中位数为合并后数组中间那个数 +/// 如果两个数组的长度之和为偶数时,则中位数为中间两个数之和的平均数 +impl Solution { + /// 方法1:按升序合并两个数组,取中位数 + pub fn find_median_sorted_arrays(nums1: Vec, nums2: Vec) -> f64 { + if nums1.len() == 1 && nums2.is_empty() { + return nums1[0] as f64; + } + + if nums2.len() == 1 && nums1.is_empty() { + return nums2[0] as f64; + } + + let mut v = Vec::with_capacity(nums1.len() + nums2.len()); + let (mut index1, mut index2) = (0, 0); + + while index1 < nums1.len() || index2 < nums2.len() { + if index1 < nums1.len() && index2 < nums2.len() { + if nums1[index1] < nums2[index2] { + v.push(nums1[index1]); + index1 += 1; + } else { + v.push(nums2[index2]); + index2 += 1; + } + } else if index1 < nums1.len() { + v.push(nums1[index1]); + index1 += 1; + } else { + v.push(nums2[index2]); + index2 += 1; + } + } + + if v.len() % 2 == 1 { + v[v.len() / 2] as f64 + } else { + (v[v.len() / 2 - 1] as f64 + v[v.len() / 2] as f64) / 2f64 + } + } +} diff --git a/src/bin/merge-intervals.rs b/src/bin/merge-intervals.rs new file mode 100644 index 00000000..caccbfdb --- /dev/null +++ b/src/bin/merge-intervals.rs @@ -0,0 +1,26 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn merge(intervals: Vec>) -> Vec> { + let mut intervals = intervals; + intervals.sort(); + + let mut result = vec![vec![intervals[0][0], intervals[0][1]]]; + + for i in intervals.into_iter().skip(1) { + if let Some(v) = result.last_mut() { + if i[0] >= v[0] && i[0] <= v[1] { + v[1] = v[1].max(i[1]); + } else { + result.push(i); + } + } + } + + result + } +} diff --git a/src/bin/merge-k-sorted-lists.rs b/src/bin/merge-k-sorted-lists.rs new file mode 100644 index 00000000..9f73933f --- /dev/null +++ b/src/bin/merge-k-sorted-lists.rs @@ -0,0 +1,88 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +// Definition for singly-linked list. +#[derive(PartialEq, Eq, Clone, Debug)] +pub struct ListNode { + pub val: i32, + pub next: Option>, +} + +impl ListNode { + #[inline] + fn new(val: i32) -> Self { + ListNode { next: None, val } + } +} + +impl Solution { + pub fn merge_k_lists1(lists: Vec>>) -> Option> { + let mut lists = lists; + let (mut index, mut min_value) = (0usize, None); + for (i, v) in lists.iter().enumerate() { + match v { + Some(x) => { + if min_value.is_none() { + min_value = Some(x.val); + index = i; + } else { + if min_value.as_ref().unwrap().gt(&x.val) { + min_value = Some(x.val); + index = i; + } + } + } + None => (), + } + } + + if index == 0 && min_value.is_none() { + return None; + } + let mut root = lists[index].take(); + lists[index] = root.as_mut().unwrap().next.take(); + + root.as_mut().unwrap().next = Self::merge_k_lists(lists); + + root + } + + pub fn merge_k_lists(lists: Vec>>) -> Option> { + let mut lists = lists; + + if lists.is_empty() { + return None; + } else if lists.len() == 1 { + return lists[0].take(); + } + + let mut start = lists[0].take(); + let mut i = 1usize; + while i < lists.len() { + start = Self::f(vec![start, lists[i].take()]); + i += 1; + } + + start + } + + fn f(mut lists: Vec>>) -> Option> { + match (lists[0].take(), lists[1].take()) { + (Some(mut x), Some(mut y)) => { + if x.val < y.val { + x.next = Self::f(vec![x.next.take(), Some(y)]); + Some(x) + } else { + y.next = Self::f(vec![Some(x), y.next.take()]); + Some(y) + } + } + (Some(x), None) => Some(x), + (None, Some(y)) => Some(y), + (None, None) => None, + } + } +} diff --git a/src/bin/merge-nodes-in-between-zeros.rs b/src/bin/merge-nodes-in-between-zeros.rs new file mode 100644 index 00000000..ea5cf601 --- /dev/null +++ b/src/bin/merge-nodes-in-between-zeros.rs @@ -0,0 +1,42 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +// Definition for singly-linked list. +#[derive(PartialEq, Eq, Clone, Debug)] +pub struct ListNode { + pub val: i32, + pub next: Option>, +} + +impl ListNode { + #[inline] + fn new(val: i32) -> Self { + ListNode { next: None, val } + } +} + +impl Solution { + pub fn merge_nodes(mut head: Option>) -> Option> { + let mut result = ListNode::new(0); + let mut next = &mut result.next; + let mut current = head.unwrap().next; + + let mut val = 0; + while current.is_some() { + if current.as_ref().unwrap().val == 0 { + next.insert(Box::new(ListNode::new(val))); + val = 0; + next = &mut next.as_mut().unwrap().next; + } else { + val += current.as_ref().unwrap().val; + } + + current = current.unwrap().next; + } + + result.next.take() + } +} diff --git a/src/bin/merge-sorted-array.rs b/src/bin/merge-sorted-array.rs new file mode 100644 index 00000000..9c71ca69 --- /dev/null +++ b/src/bin/merge-sorted-array.rs @@ -0,0 +1,28 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn merge(nums1: &mut Vec, m: i32, nums2: &mut Vec, n: i32) { + let (mut m, mut n) = (m - 1, n - 1); + for i in (0..nums1.len()).rev() { + if m < 0 { + nums1[i] = nums2[n as usize]; + n -= 1; + } else if n < 0 { + nums1[i] = nums1[m as usize]; + m -= 1; + } else { + if nums1[m as usize] > nums2[n as usize] { + nums1[i] = nums1[m as usize]; + m -= 1; + } else { + nums1[i as usize] = nums2[n as usize]; + n -= 1; + } + } + } + } +} diff --git a/src/bin/merge-strings-alternately.rs b/src/bin/merge-strings-alternately.rs new file mode 100644 index 00000000..13e7896b --- /dev/null +++ b/src/bin/merge-strings-alternately.rs @@ -0,0 +1,23 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn merge_alternately(word1: String, word2: String) -> String { + let mut ans = Vec::with_capacity(word1.len() + word2.len()); + let mut i = 0; + + while i < word1.len() && i < word2.len() { + ans.push(word1.as_bytes()[i]); + ans.push(word2.as_bytes()[i]); + i += 1; + } + + ans.extend(word1.as_bytes()[i..].iter()); + ans.extend(word2.as_bytes()[i..].iter()); + + unsafe { String::from_utf8_unchecked(ans) } + } +} diff --git a/src/bin/merge-two-2d-arrays-by-summing-values.rs b/src/bin/merge-two-2d-arrays-by-summing-values.rs new file mode 100644 index 00000000..a64b7baa --- /dev/null +++ b/src/bin/merge-two-2d-arrays-by-summing-values.rs @@ -0,0 +1,36 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn merge_arrays(nums1: Vec>, nums2: Vec>) -> Vec> { + let mut result = vec![]; + let (mut i, mut j) = (0, 0); + + while i < nums1.len() && j < nums2.len() { + if nums1[i][0] < nums2[j][0] { + result.push(nums1[i].clone()); + i += 1; + } else if nums1[i][0] > nums2[j][0] { + result.push(nums2[j].clone()); + j += 1; + } else { + result.push(vec![nums1[i][0], nums1[i][1] + nums2[j][1]]); + i += 1; + j += 1; + } + } + + if i < nums1.len() { + result.extend_from_slice(&nums1[i..]); + } + + if j < nums2.len() { + result.extend_from_slice(&nums2[j..]); + } + + result + } +} diff --git a/src/bin/merge-two-binary-trees.rs b/src/bin/merge-two-binary-trees.rs new file mode 100644 index 00000000..55861c70 --- /dev/null +++ b/src/bin/merge-two-binary-trees.rs @@ -0,0 +1,76 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +// Definition for a binary tree node. +#[derive(Debug, PartialEq, Eq)] +pub struct TreeNode { + pub val: i32, + pub left: Option>>, + pub right: Option>>, +} + +impl TreeNode { + #[inline] + pub fn new(val: i32) -> Self { + TreeNode { + val, + left: None, + right: None, + } + } +} + +use std::cell::RefCell; +use std::rc::Rc; + +impl Solution { + pub fn merge_trees( + t1: Option>>, + t2: Option>>, + ) -> Option>> { + if t1.is_some() { + Self::scan(Some(Rc::clone(t1.as_ref().unwrap())), t2); + t1 + } else { + t2 + } + } + + fn scan(t1: Option>>, t2: Option>>) { + if t1.is_none() { + return; + } else if t1.is_some() && t2.is_some() { + t1.as_ref().unwrap().borrow_mut().val += t2.as_ref().unwrap().borrow().val; + if t1.as_ref().unwrap().borrow().left.is_some() { + Self::scan( + Some(Rc::clone( + t1.as_ref().unwrap().borrow_mut().left.as_ref().unwrap(), + )), + Rc::clone(t2.as_ref().unwrap()).borrow_mut().left.take(), + ); + } else { + t1.as_ref().unwrap().borrow_mut().left = + t2.as_ref().unwrap().borrow_mut().left.take(); + } + + if t1.as_ref().unwrap().borrow().right.is_some() { + Self::scan( + Some(Rc::clone( + Rc::clone(t1.as_ref().unwrap()) + .borrow_mut() + .right + .as_ref() + .unwrap(), + )), + Rc::clone(t2.as_ref().unwrap()).borrow_mut().right.take(), + ); + } else { + t1.as_ref().unwrap().borrow_mut().right = + t2.as_ref().unwrap().borrow_mut().right.take(); + } + } + } +} diff --git a/src/bin/merge-two-sorted-lists.rs b/src/bin/merge-two-sorted-lists.rs new file mode 100644 index 00000000..6c6273d5 --- /dev/null +++ b/src/bin/merge-two-sorted-lists.rs @@ -0,0 +1,41 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +// Definition for singly-linked list. +#[derive(PartialEq, Eq, Clone, Debug)] +pub struct ListNode { + pub val: i32, + pub next: Option>, +} + +impl ListNode { + #[inline] + fn new(val: i32) -> Self { + ListNode { next: None, val } + } +} + +impl Solution { + pub fn merge_two_lists( + l1: Option>, + l2: Option>, + ) -> Option> { + match (l1, l2) { + (Some(mut x), Some(mut y)) => { + if x.val <= y.val { + x.next = Self::merge_two_lists(x.next, Some(y)); + Some(x) + } else { + y.next = Self::merge_two_lists(Some(x), y.next); + Some(y) + } + } + (None, Some(y)) => Some(y), + (Some(x), None) => Some(x), + (None, None) => None, + } + } +} diff --git a/src/bin/middle-of-the-linked-list.rs b/src/bin/middle-of-the-linked-list.rs new file mode 100644 index 00000000..75a6b016 --- /dev/null +++ b/src/bin/middle-of-the-linked-list.rs @@ -0,0 +1,35 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +// Definition for singly-linked list. +#[derive(PartialEq, Eq, Clone, Debug)] +pub struct ListNode { + pub val: i32, + pub next: Option>, +} + +impl ListNode { + #[inline] + fn new(val: i32) -> Self { + ListNode { next: None, val } + } +} + +impl Solution { + pub fn middle_node(head: Option>) -> Option> { + let (mut s1, mut s2) = (&head, &head); + + while s2.as_ref().unwrap().next.is_some() { + s1 = &s1.as_ref().unwrap().next; + s2 = &s2.as_ref().unwrap().next; + if s2.as_ref().unwrap().next.is_some() { + s2 = &s2.as_ref().unwrap().next; + } + } + + s1.clone() + } +} diff --git a/src/bin/min-cost-climbing-stairs.rs b/src/bin/min-cost-climbing-stairs.rs new file mode 100644 index 00000000..37296b45 --- /dev/null +++ b/src/bin/min-cost-climbing-stairs.rs @@ -0,0 +1,19 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn min_cost_climbing_stairs(cost: Vec) -> i32 { + let (mut s1, mut s2) = (cost[0], cost[1]); + + for &i in cost[2..].iter() { + let s = i + s1.min(s2); + s1 = s2; + s2 = s; + } + + s1.min(s2) + } +} diff --git a/src/bin/min-max-game.rs b/src/bin/min-max-game.rs new file mode 100644 index 00000000..01ac77fb --- /dev/null +++ b/src/bin/min-max-game.rs @@ -0,0 +1,23 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn min_max_game(mut nums: Vec) -> i32 { + while nums.len() != 1 { + let mut new_nums = Vec::with_capacity(nums.len() / 2); + for i in 0..nums.len() / 2 { + if i % 2 == 0 { + new_nums.push(nums[2 * i].min(nums[2 * i + 1])); + } else { + new_nums.push(nums[2 * i].max(nums[2 * i + 1])); + } + } + + nums = new_nums; + } + nums[0] + } +} diff --git a/src/bin/min-stack.rs b/src/bin/min-stack.rs new file mode 100644 index 00000000..d89d7676 --- /dev/null +++ b/src/bin/min-stack.rs @@ -0,0 +1,62 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +/** + * Your MinStack object will be instantiated and called as such: + * let obj = MinStack::new(); + * obj.push(val); + * obj.pop(); + * let ret_3: i32 = obj.top(); + * let ret_4: i32 = obj.get_min(); + */ +struct MinStack { + data: Vec, + min_stack: Vec, +} + +/** + * `&self` means the method takes an immutable reference. + * If you need a mutable reference, change it to `&mut self` instead. + */ +impl MinStack { + /** initialize your data structure here. */ + fn new() -> Self { + Self { + data: vec![], + min_stack: vec![], + } + } + + fn push(&mut self, val: i32) { + self.data.push(val); + + if !self.min_stack.is_empty() { + if self.min_stack.last().unwrap().lt(&val) { + return; + } + } + + self.min_stack.push(val); + } + + fn pop(&mut self) { + if let Some(x) = self.data.pop() { + if let Some(&y) = self.min_stack.last() { + if y == x { + self.min_stack.pop(); + } + } + } + } + + fn top(&self) -> i32 { + self.data.last().unwrap().clone() + } + + fn get_min(&self) -> i32 { + self.min_stack.last().unwrap().clone() + } +} diff --git a/src/bin/minimize-result-by-adding-parentheses-to-expression.rs b/src/bin/minimize-result-by-adding-parentheses-to-expression.rs new file mode 100644 index 00000000..2767b9b5 --- /dev/null +++ b/src/bin/minimize-result-by-adding-parentheses-to-expression.rs @@ -0,0 +1,66 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() { + assert_eq!( + Solution::minimize_result("12+34".to_string()), + "1(2+3)4".to_string() + ); +} + +struct Solution; + +impl Solution { + pub fn minimize_result(expression: String) -> String { + let mut expression = expression.split('+'); + let left = expression.next().unwrap(); + let right = expression.next().unwrap(); + + let mut left_index = 0; + let mut right_index = 0; + let mut min = i32::MAX; + + for i in 0..left.len() { + let l1 = if i == 0 { + 1 + } else { + left[..i].parse::().unwrap() + }; + + let l2 = if i < left.len() { + left[i..].parse::().unwrap() + } else { + 1 + }; + + for j in 1..=right.len() { + let l3 = if j == 0 { + 1 + } else { + right[..j].parse::().unwrap() + }; + + let l4 = if j < right.len() { + right[j..].parse::().unwrap() + } else { + 1 + }; + + let c = l1 * (l2 + l3) * l4; + + if c < min { + left_index = i; + right_index = j; + min = c; + } + } + } + + format!( + "{}({}+{}){}", + &left[..left_index], + &left[left_index..], + &right[..right_index], + &right[right_index..] + ) + } +} diff --git a/src/bin/minimize-xor.rs b/src/bin/minimize-xor.rs new file mode 100644 index 00000000..8ec5a13e --- /dev/null +++ b/src/bin/minimize-xor.rs @@ -0,0 +1,21 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn minimize_xor(mut num1: i32, num2: i32) -> i32 { + let mut c1 = num1.count_ones(); + let mut c2 = num2.count_ones(); + while c2 < c1 { + num1 &= num1 - 1; + c2 += 1; + } + while c2 > c1 { + num1 |= num1 + 1; + c2 -= 1 + } + num1 + } +} diff --git a/src/bin/minimum-absolute-difference-in-bst.rs b/src/bin/minimum-absolute-difference-in-bst.rs new file mode 100644 index 00000000..8924607c --- /dev/null +++ b/src/bin/minimum-absolute-difference-in-bst.rs @@ -0,0 +1,56 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +// Definition for a binary tree node. +#[derive(Debug, PartialEq, Eq)] +pub struct TreeNode { + pub val: i32, + pub left: Option>>, + pub right: Option>>, +} + +impl TreeNode { + #[inline] + pub fn new(val: i32) -> Self { + TreeNode { + val, + left: None, + right: None, + } + } +} + +use std::cell::RefCell; +use std::rc::Rc; + +impl Solution { + pub fn get_minimum_difference(root: Option>>) -> i32 { + let mut v = vec![]; + let mut stack = vec![root]; + + while let Some(x) = stack.pop() { + if let Some(y) = x { + v.push(y.borrow().val); + if let Some(z) = y.borrow_mut().left.take() { + stack.push(Some(z)); + } + if let Some(o) = y.borrow_mut().right.take() { + stack.push(Some(o)); + } + } + } + + v.sort(); + + let mut x = std::i32::MAX; + + for i in 1..v.len() { + x = x.min(v[i] - v[i - 1]); + } + + x + } +} diff --git a/src/bin/minimum-absolute-difference.rs b/src/bin/minimum-absolute-difference.rs new file mode 100644 index 00000000..802dd8d7 --- /dev/null +++ b/src/bin/minimum-absolute-difference.rs @@ -0,0 +1,29 @@ +#![allow(dead_code, unused, unused_variables)] + +use std::vec; + +fn main() {} + +struct Solution; + +impl Solution { + pub fn minimum_abs_difference(mut arr: Vec) -> Vec> { + arr.sort(); + + let mut diff = arr[1] - arr[0]; + let mut v = vec![vec![arr[0], arr[1]]]; + for i in 2..arr.len() { + match (arr[i] - arr[i - 1]).cmp(&diff) { + std::cmp::Ordering::Less => { + diff = arr[i] - arr[i - 1]; + v = vec![]; + v.push(vec![arr[i - 1], arr[i]]); + } + + std::cmp::Ordering::Equal => v.push(vec![arr[i - 1], arr[i]]), + std::cmp::Ordering::Greater => {} + } + } + v + } +} diff --git a/src/bin/minimum-additions-to-make-valid-string.rs b/src/bin/minimum-additions-to-make-valid-string.rs new file mode 100644 index 00000000..43a8318e --- /dev/null +++ b/src/bin/minimum-additions-to-make-valid-string.rs @@ -0,0 +1,50 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn add_minimum(word: String) -> i32 { + let mut result = 0; + let mut index = 0usize; + let word = word.as_bytes(); + while index < word.len() { + match word[index] { + b'a' => match (word.get(index + 1), word.get(index + 2)) { + (Some(b'b'), Some(b'c')) => index += 3, + (Some(b'b'), _) => { + index += 2; + result += 1; + } + (Some(b'c'), _) => { + index += 2; + result += 1; + } + _ => { + index += 1; + result += 2; + } + }, + b'b' => match word.get(index + 1) { + Some(b'c') => { + index += 2; + result += 1; + } + + _ => { + index += 1; + result += 2; + } + }, + b'c' => { + index += 1; + result += 2; + } + _ => unreachable!(), + } + } + + result + } +} diff --git a/src/bin/minimum-changes-to-make-alternating-binary-string.rs b/src/bin/minimum-changes-to-make-alternating-binary-string.rs new file mode 100644 index 00000000..82cc989b --- /dev/null +++ b/src/bin/minimum-changes-to-make-alternating-binary-string.rs @@ -0,0 +1,27 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn min_operations(s: String) -> i32 { + let (mut r1, mut r2) = (0, 0); + let (mut s1, mut s2) = (b'1', b'0'); + + for &i in s.as_bytes() { + if i != s1 { + r1 += 1; + } + + if i != s2 { + r2 += 1; + } + + s1 = if s1 == b'1' { b'0' } else { b'1' }; + s2 = if s2 == b'1' { b'0' } else { b'1' }; + } + + r1.min(r2) + } +} diff --git a/src/bin/minimum-cost-to-move-chips-to-the-same-position.rs b/src/bin/minimum-cost-to-move-chips-to-the-same-position.rs new file mode 100644 index 00000000..542b532f --- /dev/null +++ b/src/bin/minimum-cost-to-move-chips-to-the-same-position.rs @@ -0,0 +1,21 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn min_cost_to_move_chips(position: Vec) -> i32 { + let (mut s, mut n) = (0, 0); // 奇数、偶数的个数 + + for i in position { + if i % 2 == 0 { + s += 1; + } else { + n += 1; + } + } + + s.min(n) + } +} diff --git a/src/bin/minimum-cuts-to-divide-a-circle.rs b/src/bin/minimum-cuts-to-divide-a-circle.rs new file mode 100644 index 00000000..89d169e1 --- /dev/null +++ b/src/bin/minimum-cuts-to-divide-a-circle.rs @@ -0,0 +1,17 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn number_of_cuts(n: i32) -> i32 { + if n % 2 == 0 { + n / 2 + } else if n == 1 { + 0 + } else { + n + } + } +} diff --git a/src/bin/minimum-depth-of-binary-tree.rs b/src/bin/minimum-depth-of-binary-tree.rs new file mode 100644 index 00000000..9e8a9477 --- /dev/null +++ b/src/bin/minimum-depth-of-binary-tree.rs @@ -0,0 +1,90 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +// Definition for a binary tree node. +#[derive(Debug, PartialEq, Eq)] +pub struct TreeNode { + pub val: i32, + pub left: Option>>, + pub right: Option>>, +} + +impl TreeNode { + #[inline] + pub fn new(val: i32) -> Self { + TreeNode { + val, + left: None, + right: None, + } + } +} + +use std::cell::RefCell; +use std::rc::Rc; + +impl Solution { + pub fn min_depth1(root: Option>>) -> i32 { + if root.is_none() { + return 0; + } + + let root = root.unwrap(); + + if root.borrow().left.is_none() && root.borrow().right.is_none() { + 1 + } else if root.borrow().left.is_none() && root.borrow().right.is_some() { + 1 + Solution::min_depth(RefCell::borrow_mut(&root).right.take()) + } else if root.borrow().left.is_some() && root.borrow().right.is_none() { + 1 + Solution::min_depth(RefCell::borrow_mut(&root).left.take()) + } else { + let left = 1 + Solution::min_depth(RefCell::borrow_mut(&root).left.take()); + let right = 1 + Solution::min_depth(RefCell::borrow_mut(&root).right.take()); + + if left > right { + return right; + } + + left + } + } + + pub fn min_depth(root: Option>>) -> i32 { + if root.is_none() { + return 0; + } + + let mut height = 1; + let mut v = vec![(root, height)]; + + let mut index = 0; + + while index < v.len() { + if v[index].0.as_ref().unwrap().borrow().left.is_none() + && v[index].0.as_ref().unwrap().borrow().right.is_none() + { + height = v[index].1; + break; + } + + if v[index].0.as_ref().unwrap().borrow().left.is_some() { + let x = v[index].1 + 1; + let left = v[index].0.as_ref().unwrap().borrow_mut().left.take(); + v.push((left, x)); + } + + if v[index].0.as_ref().unwrap().borrow().right.is_some() { + let x = v[index].1 + 1; + let right = v[index].0.as_ref().unwrap().borrow_mut().right.take(); + v.push((right, x)); + } + + index += 1; + } + + height + } +} diff --git a/src/bin/minimum-distance-between-bst-nodes.rs b/src/bin/minimum-distance-between-bst-nodes.rs new file mode 100644 index 00000000..e8f2e3c5 --- /dev/null +++ b/src/bin/minimum-distance-between-bst-nodes.rs @@ -0,0 +1,53 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +use std::cell::RefCell; +use std::rc::Rc; + +fn main() {} + +struct Solution; + +// Definition for a binary tree node. +#[derive(Debug, PartialEq, Eq)] +pub struct TreeNode { + pub val: i32, + pub left: Option>>, + pub right: Option>>, +} + +impl TreeNode { + #[inline] + pub fn new(val: i32) -> Self { + TreeNode { + val, + left: None, + right: None, + } + } +} + +impl Solution { + pub fn min_diff_in_bst(root: Option>>) -> i32 { + fn expand(root: Option>>, list: &mut Vec) { + if root.is_none() { + return; + } + // 中序遍历,因为这是二叉搜索树 + let root = root.unwrap(); + expand(root.borrow_mut().left.take(), list); + list.push(root.borrow().val); + expand(root.borrow_mut().right.take(), list); + } + + let mut list = vec![]; + expand(root, &mut list); + + let mut result = i32::MAX; + + for i in 1..list.len() { + result = result.min(list[i] - list[i - 1]); + } + + result + } +} diff --git a/src/bin/minimum-falling-path-sum.rs b/src/bin/minimum-falling-path-sum.rs new file mode 100644 index 00000000..0251b0f0 --- /dev/null +++ b/src/bin/minimum-falling-path-sum.rs @@ -0,0 +1,34 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn min_falling_path_sum(mut matrix: Vec>) -> i32 { + let n = matrix.len(); + + for i in (0..n - 1).rev() { + for j in 0..n { + if j == 0 { + matrix[i][j] = matrix[i][j] + matrix[i + 1][j].min(matrix[i + 1][j + 1]); + } else if j == n - 1 { + matrix[i][j] = matrix[i][j] + matrix[i + 1][j - 1].min(matrix[i + 1][j]); + } else { + matrix[i][j] = matrix[i][j] + + matrix[i + 1][j - 1] + .min(matrix[i + 1][j]) + .min(matrix[i + 1][j + 1]); + } + } + } + + let mut r = matrix[0][0]; + + for i in 1..n { + r = r.min(matrix[0][i]); + } + + r + } +} diff --git a/src/bin/minimum-flips-to-make-a-or-b-equal-to-c.rs b/src/bin/minimum-flips-to-make-a-or-b-equal-to-c.rs new file mode 100644 index 00000000..89c358d8 --- /dev/null +++ b/src/bin/minimum-flips-to-make-a-or-b-equal-to-c.rs @@ -0,0 +1,56 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + assert_eq!(3, Solution::min_flips(2, 6, 5)); +} + +struct Solution; + +impl Solution { + pub fn min_flips1(a: i32, b: i32, c: i32) -> i32 { + let mut count = 0; + + for i in 0..32 { + let a1 = ((a as u32) << (31 - i)) >> 31; + let b1 = ((b as u32) << (31 - i)) >> 31; + let c1 = ((c as u32) << (31 - i)) >> 31; + + if c1 == 0 { + if (a1 == 1 && b1 == 0) || (a1 == 0 && b1 == 1) { + count += 1; + } else if a1 == 1 && b1 == 1 { + count += 2; + } + } else { + if a1 == 0 && b1 == 0 { + count += 1; + } + } + } + count + } + + // 任何数 &1 都只会剩下最后位的数字 + pub fn min_flips(a: i32, b: i32, c: i32) -> i32 { + let mut count = 0; + + for i in 0..32 { + let a1 = (a >> i) & 1; + let b1 = (b >> i) & 1; + let c1 = (c >> i) & 1; + + if c1 == 0 { + if (a1 == 1 && b1 == 0) || (a1 == 0 && b1 == 1) { + count += 1; + } else if a1 == 1 && b1 == 1 { + count += 2; + } + } else { + if a1 == 0 && b1 == 0 { + count += 1; + } + } + } + count + } +} diff --git a/src/bin/minimum-garden-perimeter-to-collect-enough-apples.rs b/src/bin/minimum-garden-perimeter-to-collect-enough-apples.rs new file mode 100644 index 00000000..cce64533 --- /dev/null +++ b/src/bin/minimum-garden-perimeter-to-collect-enough-apples.rs @@ -0,0 +1,20 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn minimum_perimeter(needed_apples: i64) -> i64 { + let mut total = 0; + for i in 1.. { + let s = 8 * 3 * (i + 1) * i / 2 - 12 * i; + total += s; + if total >= needed_apples { + return 8 * i; + } + } + + unreachable!() + } +} diff --git a/src/bin/minimum-increment-to-make-array-unique.rs b/src/bin/minimum-increment-to-make-array-unique.rs new file mode 100644 index 00000000..22745f8d --- /dev/null +++ b/src/bin/minimum-increment-to-make-array-unique.rs @@ -0,0 +1,45 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + assert_eq!(1, Solution::min_increment_for_unique(vec![1, 2, 2])); + assert_eq!( + 6, + Solution::min_increment_for_unique(vec![3, 2, 1, 2, 1, 7]) + ); + assert_eq!(1, Solution::min_increment_for_unique(vec![40000, 40000])); +} + +struct Solution; + +impl Solution { + pub fn min_increment_for_unique1(a: Vec) -> i32 { + let mut array = vec![0; 40000 * 2]; + let mut count = 0; + for &i in a.iter() { + let mut i = i as usize; + while array[i] != 0 { + i += 1; + count += 1; + } + array[i] = 1; + } + + count + } + + /// 贪心算法在于每个子问题的局部最优解会指向全局最优解。 + /// 显然在对数组排序之后,可以通过保证数组的最后一个元素, + /// 经过+1操作后比前面所有元素大即可,此时子问题的最优解会收敛于全局最优解 + pub fn min_increment_for_unique(mut a: Vec) -> i32 { + a.sort(); + let mut count = 0; + for i in 1..a.len() { + if a[i] <= a[i - 1] { + count += a[i - 1] - a[i] + 1; + a[i] = a[i - 1] + 1; + } + } + + count + } +} diff --git a/src/bin/minimum-index-sum-of-two-lists.rs b/src/bin/minimum-index-sum-of-two-lists.rs new file mode 100644 index 00000000..2a982e33 --- /dev/null +++ b/src/bin/minimum-index-sum-of-two-lists.rs @@ -0,0 +1,36 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn find_restaurant(list1: Vec, list2: Vec) -> Vec { + let m = list1 + .into_iter() + .enumerate() + .map(|x| (x.1, x.0)) + .collect::>(); + + let mut data = vec![]; + let mut index = usize::MAX; + + for (i, v) in list2.into_iter().enumerate() { + if i > index { + break; + } + + if let Some(&x) = m.get(&v) { + if i + x <= index { + if i + x < index { + data.clear(); + } + data.push(v); + index = i + x; + } + } + } + + data + } +} diff --git a/src/bin/minimum-moves-to-reach-target-score.rs b/src/bin/minimum-moves-to-reach-target-score.rs new file mode 100644 index 00000000..b40383b8 --- /dev/null +++ b/src/bin/minimum-moves-to-reach-target-score.rs @@ -0,0 +1,30 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn min_moves(target: i32, max_doubles: i32) -> i32 { + let mut max_doubles = max_doubles; + let mut target = target; + let mut result = 0; + while target > 1 { + if target % 2 == 1 { + target -= 1; + result += 1; + } else { + if max_doubles > 0 { + target /= 2; + result += 1; + max_doubles -= 1; + } else { + result += target - 1; + target = 1; + } + } + } + + result + } +} diff --git a/src/bin/minimum-number-game.rs b/src/bin/minimum-number-game.rs new file mode 100644 index 00000000..50b33e16 --- /dev/null +++ b/src/bin/minimum-number-game.rs @@ -0,0 +1,18 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn number_game(nums: Vec) -> Vec { + let mut nums = nums; + nums.sort_unstable(); + + for i in (1..nums.len()).step_by(2) { + nums.swap(i, i - 1); + } + + nums + } +} diff --git a/src/bin/minimum-number-of-coins-to-be-added.rs b/src/bin/minimum-number-of-coins-to-be-added.rs new file mode 100644 index 00000000..d3b2e3b6 --- /dev/null +++ b/src/bin/minimum-number-of-coins-to-be-added.rs @@ -0,0 +1,24 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn minimum_added_coins(mut coins: Vec, target: i32) -> i32 { + coins.sort_unstable(); + let mut ans = 0; + let mut s = 1; + let mut i = 0; + while s <= target { + if i < coins.len() && coins[i] <= s { + s += coins[i]; + i += 1; + } else { + s *= 2; // 必须添加 s + ans += 1; + } + } + ans + } +} diff --git a/src/bin/minimum-number-of-operations-to-make-array-empty.rs b/src/bin/minimum-number-of-operations-to-make-array-empty.rs new file mode 100644 index 00000000..1f55eaea --- /dev/null +++ b/src/bin/minimum-number-of-operations-to-make-array-empty.rs @@ -0,0 +1,29 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn min_operations(nums: Vec) -> i32 { + let mut hash = std::collections::HashMap::new(); + for i in nums { + hash.entry(i).and_modify(|x| *x += 1).or_insert(1); + } + let mut r = 0; + + for (_, v) in hash { + if v == 1 { + return -1; + } + + if v % 3 == 0 { + r += v / 3; + } else { + r += v / 3 + 1; + } + } + + r + } +} diff --git a/src/bin/minimum-number-of-pushes-to-type-word-i.rs b/src/bin/minimum-number-of-pushes-to-type-word-i.rs new file mode 100644 index 00000000..5a0f6d85 --- /dev/null +++ b/src/bin/minimum-number-of-pushes-to-type-word-i.rs @@ -0,0 +1,26 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() { + assert_eq!(Solution::minimum_pushes("abcde".into()), 5); + assert_eq!(Solution::minimum_pushes("xycdefghij".into()), 12); + assert_eq!( + Solution::minimum_pushes("amrvxnhsewkoipjyuclgtdbfq".into()), + 52 + ); +} + +struct Solution; + +impl Solution { + pub fn minimum_pushes(word: String) -> i32 { + let mut r = 0; + let mut len = word.len(); + match len { + 0..=8 => len as i32, + 9..=16 => 8 + (len as i32 - 8) * 2, + 17..=24 => 24 + (len as i32 - 16) * 3, + 25..=26 => 48 + (len as i32 - 24) * 4, + _ => unreachable!(), + } + } +} diff --git a/src/bin/minimum-operations-to-exceed-threshold-value-i.rs b/src/bin/minimum-operations-to-exceed-threshold-value-i.rs new file mode 100644 index 00000000..dd2ee5c3 --- /dev/null +++ b/src/bin/minimum-operations-to-exceed-threshold-value-i.rs @@ -0,0 +1,11 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn min_operations(nums: Vec, k: i32) -> i32 { + nums.into_iter().filter(|x| *x < k).count() as _ + } +} diff --git a/src/bin/minimum-operations-to-halve-array-sum.rs b/src/bin/minimum-operations-to-halve-array-sum.rs new file mode 100644 index 00000000..92b65f71 --- /dev/null +++ b/src/bin/minimum-operations-to-halve-array-sum.rs @@ -0,0 +1,36 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn halve_array(nums: Vec) -> i32 { + #[derive(Clone, Copy, PartialEq, PartialOrd)] + struct F64(f64); + + impl Eq for F64 {} + + impl Ord for F64 { + fn cmp(&self, other: &Self) -> std::cmp::Ordering { + self.partial_cmp(other).unwrap() + } + } + + use std::collections::binary_heap::BinaryHeap; + let sum = nums.iter().map(|x| *x as f64).sum::(); + let mut heap: BinaryHeap = nums.into_iter().map(|x| F64(x as f64)).collect(); + let mut s = 0f64; + let mut r = 0; + + loop { + r += 1; + let p = heap.pop().unwrap(); + if sum - s - p.0 / 2f64 <= sum / 2f64 { + return r; + } + heap.push(F64(p.0 / 2f64)); + s += p.0 / 2f64; + } + } +} diff --git a/src/bin/minimum-operations-to-make-a-special-number.rs b/src/bin/minimum-operations-to-make-a-special-number.rs new file mode 100644 index 00000000..d82cd5d2 --- /dev/null +++ b/src/bin/minimum-operations-to-make-a-special-number.rs @@ -0,0 +1,45 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn minimum_operations(num: String) -> i32 { + let mut result = num.len() as i32; + let mut s = vec![false, false]; + let len = num.len() as i32 - 1; + + for (i, u) in num.bytes().enumerate().rev() { + match u { + b'0' => { + // 00结尾 + if s[0] { + result = result.min(len - i as i32 + 1); + } + s[0] = true; + } + b'2' | b'7' => { + // 2, 5 + // 7, 5 + if s[1] { + result = result.min(len - i as i32 + 1); + } + } + b'5' => { + // 5,0 + if s[0] { + result = result.min(len - i as i32 + 1); + } + s[1] = true; + } + _ => {} + } + } + + if s[0] { + result = result.min(len); + } + result + } +} diff --git a/src/bin/minimum-operations-to-make-the-array-increasing.rs b/src/bin/minimum-operations-to-make-the-array-increasing.rs new file mode 100644 index 00000000..fe71ae70 --- /dev/null +++ b/src/bin/minimum-operations-to-make-the-array-increasing.rs @@ -0,0 +1,20 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn min_operations(mut nums: Vec) -> i32 { + let mut r = 0; + + for i in 1..nums.len() { + if nums[i] <= nums[i - 1] { + r += nums[i - 1] + 1 - nums[i]; + nums[i] = nums[i - 1] + 1; + } + } + + r + } +} diff --git a/src/bin/minimum-path-cost-in-a-grid.rs b/src/bin/minimum-path-cost-in-a-grid.rs new file mode 100644 index 00000000..6df0bba7 --- /dev/null +++ b/src/bin/minimum-path-cost-in-a-grid.rs @@ -0,0 +1,27 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn min_path_cost(mut grid: Vec>, move_cost: Vec>) -> i32 { + // let mut v = vec![vec![0; grid[0].len()]; grid.len()]; + // for i in 0..grid[0].len() { + // v[grid.len() - 1][i] = grid[grid.len() - 1][i]; + // } + + for i in (0..grid.len() - 1).rev() { + for j in 0..grid[0].len() { + let mut min = move_cost[grid[i][j] as usize][0] + grid[i + 1][0] + grid[i][j]; + for k in 1..move_cost[grid[i][j] as usize].len() { + min = min.min(move_cost[grid[i][j] as usize][k] + grid[i + 1][k] + grid[i][j]); + } + + grid[i][j] = min; + } + } + + *grid[0].iter().min().unwrap() + } +} diff --git a/src/bin/minimum-path-sum.rs b/src/bin/minimum-path-sum.rs new file mode 100644 index 00000000..7b0ae8b0 --- /dev/null +++ b/src/bin/minimum-path-sum.rs @@ -0,0 +1,38 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn min_path_sum(grid: Vec>) -> i32 { + let mut r = vec![vec![0; grid.len()]; grid[0].len()]; + Self::scan(&mut r, &grid, 0, 0); + r[0][0] + } + + fn scan(r: &mut Vec>, grid: &Vec>, index1: usize, index2: usize) { + let (s1, s2) = (grid.len(), grid[0].len()); + if index1 == s1 - 1 && index2 == s2 - 1 { + r[index1][index2] = grid[index1][index2]; + return; + } + + if index1 >= s1 || index2 >= s2 || r[index1][index2] != 0 { + return; + } + + r[index1][index2] = grid[index1][index2]; + + Self::scan(r, grid, index1 + 1, index2); + Self::scan(r, grid, index1, index2 + 1); + + if index1 + 1 < s1 && index2 + 1 < s2 { + r[index1][index2] += r[index1 + 1][index2].min(r[index1][index2 + 1]); + } else if index1 + 1 >= s1 { + r[index1][index2] += r[index1][index2 + 1]; + } else { + r[index1][index2] += r[index1 + 1][index2]; + } + } +} diff --git a/src/bin/minimum-recolors-to-get-k-consecutive-black-blocks.rs b/src/bin/minimum-recolors-to-get-k-consecutive-black-blocks.rs new file mode 100644 index 00000000..549859bb --- /dev/null +++ b/src/bin/minimum-recolors-to-get-k-consecutive-black-blocks.rs @@ -0,0 +1,36 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +use std::io::Read; + +fn main() {} + +struct Solution; + +impl Solution { + pub fn minimum_recolors(blocks: String, k: i32) -> i32 { + let mut b = 0; + + for &i in blocks.as_bytes().into_iter().take(k as usize) { + if i == b'B' { + b += 1; + } + } + + let mut result = k - b; + let block = blocks.as_bytes(); + + for i in 1..=blocks.len() - k as usize { + if block[i - 1] == b'B' { + b -= 1; + } + + if block[i - 1 + k as usize] == b'B' { + b += 1; + } + + result = result.min(k - b); + } + + result + } +} diff --git a/src/bin/minimum-rectangles-to-cover-points.rs b/src/bin/minimum-rectangles-to-cover-points.rs new file mode 100644 index 00000000..1f26c901 --- /dev/null +++ b/src/bin/minimum-rectangles-to-cover-points.rs @@ -0,0 +1,22 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn min_rectangles_to_cover_points(points: Vec>, w: i32) -> i32 { + let mut points = points; + points.sort_by(|x, y| x[0].cmp(&y[0])); + let mut result = 0; + let mut index = 0; + for i in 0..points.len() { + if points[i][0] - points[index][0] > w { + result += 1; + index = i; + } + } + + result + 1 + } +} diff --git a/src/bin/minimum-remove-to-make-valid-parentheses.rs b/src/bin/minimum-remove-to-make-valid-parentheses.rs new file mode 100644 index 00000000..8ae7ab40 --- /dev/null +++ b/src/bin/minimum-remove-to-make-valid-parentheses.rs @@ -0,0 +1,48 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + // 先找出多余的括号,然后在移除多余的括号 + pub fn min_remove_to_make_valid(s: String) -> String { + let (mut v1, mut v2) = (0, 0); // v1:左括号多余个数,v2:右括号多余个数 + let (mut v3, mut v4) = (0, 0); // v1:左括号的总个数,v2:右括号的总个数 + for &i in s.as_bytes().into_iter() { + if i == b'(' { + v1 += 1; + v3 += 1; + } else if i == b')' { + if v1 != 0 { + v1 -= 1; + } else { + v2 += 1; + } + v4 += 1; + } + } + + let mut s1 = String::with_capacity(s.as_bytes().len() - (v1 + v2) as usize); + let mut v5 = 0; // 已有的左括号的个数 + for i in s.chars().into_iter() { + if i == '(' { + if v3 > v1 { + s1.push(i); + v3 -= 1; + v5 += 1; + } + } else if i == ')' { + if v4 > v2 && v5 != 0 { + s1.push(i); + v4 -= 1; + v5 -= 1; + } + } else { + s1.push(i); + } + } + + s1 + } +} diff --git a/src/bin/minimum-right-shifts-to-sort-the-array.rs b/src/bin/minimum-right-shifts-to-sort-the-array.rs new file mode 100644 index 00000000..3d2d5732 --- /dev/null +++ b/src/bin/minimum-right-shifts-to-sort-the-array.rs @@ -0,0 +1,35 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn minimum_right_shifts(nums: Vec) -> i32 { + let mut r = 0; + let mut f = false; + for i in 1..nums.len() { + if nums[i] < nums[i - 1] { + if f { + return -1; + } + + f = true; + } + + if f { + r += 1; + } + } + + if f { + if nums[0] >= nums[nums.len() - 1] { + r + } else { + -1 + } + } else { + 0 + } + } +} diff --git a/src/bin/minimum-rounds-to-complete-all-tasks.rs b/src/bin/minimum-rounds-to-complete-all-tasks.rs new file mode 100644 index 00000000..be4eedbb --- /dev/null +++ b/src/bin/minimum-rounds-to-complete-all-tasks.rs @@ -0,0 +1,30 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn minimum_rounds(tasks: Vec) -> i32 { + let mut count = std::collections::HashMap::new(); + for i in tasks { + *count.entry(i).or_insert(0) += 1; + } + + let mut result = 0; + for &i in count.values() { + if i < 2 { + return -1; + } + + match i % 3 { + 0 => result += i / 3, + 1 => result += (i - 4) / 3 + 2, + 2 => result += i / 3 + 1, + _ => unreachable!(), + } + } + + result + } +} diff --git a/src/bin/minimum-seconds-to-equalize-a-circular-array.rs b/src/bin/minimum-seconds-to-equalize-a-circular-array.rs new file mode 100644 index 00000000..9334ca49 --- /dev/null +++ b/src/bin/minimum-seconds-to-equalize-a-circular-array.rs @@ -0,0 +1,29 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn minimum_seconds(nums: Vec) -> i32 { + let n = nums.len(); + let mut hash = std::collections::HashMap::>::new(); + for (index, value) in nums.into_iter().enumerate() { + hash.entry(value) + .and_modify(|x| x.push(index)) + .or_insert(vec![index]); + } + + let mut result = n; + for (k, v) in hash { + let mut mx = v[0] + n - *v.last().unwrap(); + for i in 1..v.len() { + mx = mx.max(v[i] - v[i - 1]); + } + + result = result.min(mx / 2); + } + + result as i32 + } +} diff --git a/src/bin/minimum-sideway-jumps.rs b/src/bin/minimum-sideway-jumps.rs new file mode 100644 index 00000000..95323d0d --- /dev/null +++ b/src/bin/minimum-sideway-jumps.rs @@ -0,0 +1,80 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() { + assert_eq!(Solution::min_side_jumps(vec![0, 2, 1, 0, 3, 0]), 2); + assert_eq!(Solution::min_side_jumps(vec![0, 1, 1, 3, 3, 0]), 0); + assert_eq!(Solution::min_side_jumps(vec![0, 1, 2, 3, 0]), 2); +} + +struct Solution; + +impl Solution { + /// dp 这个看不懂 + pub fn min_side_jumps1(obstacles: Vec) -> i32 { + let mut dp = [1, 0, 1i64]; + // 起点都没障碍物,所以起点为0 + + for i in 1..obstacles.len() { + let a = obstacles[i]; + // 说明当前位置三个跑道都没有障碍物,因此 + let mut new_dp = [0, 0, 0]; + if a == 0 { + new_dp[0] = dp[0].min(1 + dp[1].min(dp[2])); + new_dp[1] = dp[1].min(1 + dp[0].min(dp[2])); + new_dp[2] = dp[2].min(1 + dp[0].min(dp[1])); + } else if a == 1 { + new_dp[0] = i32::MAX as i64; + new_dp[1] = dp[1].min(1 + dp[2]); + new_dp[2] = dp[2].min(1 + dp[1]); + } else if a == 2 { + new_dp[0] = dp[0].min(1 + dp[2]); + new_dp[1] = i32::MAX as i64; + new_dp[2] = dp[2].min(1 + dp[0]); + } else { + new_dp[0] = dp[0].min(1 + dp[1]); + new_dp[1] = dp[1].min(1 + dp[0]); + new_dp[2] = i32::MAX as i64; + } + + dp = new_dp; + } + + *dp[..].into_iter().min().unwrap() as i32 + } + + /// dp[i][j], 0 < i < 3, j < obstacles.len() 表示第i条跑道在第j点时的最少跳跃次数 + /// 所以dp[i][j] 可能有:1.如果有障碍物的话,就不符合要求 + /// 2.没有障碍物,就是dp[i-1][j]或者是dp[i][n]+1的最小值(因为跳跃到[i,j]位置不值可以从[i-1,j]跳跃而来,而且还可以从j处的其他跑道而来。所以统一下跳跃的次数就行了。) + pub fn min_side_jumps(obstacles: Vec) -> i32 { + // 起点都没障碍物,所以起点为0 + let mut dp = [1, 0, 1i64]; + + for i in 1..obstacles.len() { + let a = obstacles[i]; // 障碍物 + let mut new_dp = [0, 0, 0]; + let mut min = i32::MAX as i64; + + for i in 0..3 { + if a - 1 == i { + new_dp[i as usize] = i32::MAX as i64; + } else { + new_dp[i as usize] = dp[i as usize]; + } + + min = min.min(new_dp[i as usize]); + } + + // 因为任何点都可以从当前位置的其他点+1跳来,需要判断下是不是其他点+1跳过来的更短少 + + for i in 0..3 { + if a - 1 != i { + new_dp[i as usize] = new_dp[i as usize].min(min + 1); + } + } + + dp = new_dp; + } + + *dp[..].into_iter().min().unwrap() as i32 + } +} diff --git a/src/bin/minimum-string-length-after-removing-substrings.rs b/src/bin/minimum-string-length-after-removing-substrings.rs new file mode 100644 index 00000000..dd1cd470 --- /dev/null +++ b/src/bin/minimum-string-length-after-removing-substrings.rs @@ -0,0 +1,24 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn min_length(s: String) -> i32 { + let mut stack = vec![]; + for &i in s.as_bytes() { + match i { + b'B' | b'D' => match stack.last() { + Some(&x) if x + 1 == i => { + stack.pop(); + } + _ => stack.push(i), + }, + _ => stack.push(i), + } + } + + stack.len() as i32 + } +} diff --git a/src/bin/minimum-sum-of-mountain-triplets-i.rs b/src/bin/minimum-sum-of-mountain-triplets-i.rs new file mode 100644 index 00000000..2e5f0926 --- /dev/null +++ b/src/bin/minimum-sum-of-mountain-triplets-i.rs @@ -0,0 +1,43 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() { + assert_eq!(Solution::minimum_sum(vec![8, 6, 1, 5, 3]), 9); + assert_eq!(Solution::minimum_sum(vec![5, 4, 8, 7, 10, 2]), 13); + assert_eq!(Solution::minimum_sum(vec![6, 5, 4, 3, 4, 5]), -1); +} + +struct Solution; + +impl Solution { + pub fn minimum_sum(nums: Vec) -> i32 { + let (mut m1, mut m2) = (vec![0; nums.len()], vec![0; nums.len()]); + for i in 0..nums.len() { + if i == 0 { + m1[i] = nums[i]; + } else { + m1[i] = m1[i - 1].min(nums[i]); + } + } + + for i in (0..nums.len()).rev() { + if i == nums.len() - 1 { + m2[i] = nums[i]; + } else { + m2[i] = m2[i + 1].min(nums[i]); + } + } + + let mut result = i32::MAX; + for i in 1..nums.len() - 1 { + if m1[i - 1] < nums[i] && nums[i] > m2[i + 1] { + result = result.min(m1[i - 1] + m2[i + 1] + nums[i]) + } + } + + if result == i32::MAX { + -1 + } else { + result + } + } +} diff --git a/src/bin/minimum-swaps-to-make-strings-equal.rs b/src/bin/minimum-swaps-to-make-strings-equal.rs new file mode 100644 index 00000000..793c4d0e --- /dev/null +++ b/src/bin/minimum-swaps-to-make-strings-equal.rs @@ -0,0 +1,35 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + /// s1[i] != s2[i] 的个数d + /// 如果个数为奇数,则永远不可能完成 + /// 如果个数为偶数,如果x和y的个数为偶数,则 d / 2 + /// 否则 d/2+1 + pub fn minimum_swap(s1: String, s2: String) -> i32 { + let mut x = 0; + let mut c_x = 0; + for i in 0..s1.len() { + if s1.as_bytes()[i] != s2.as_bytes()[i] { + x += 1; + + if s1.as_bytes()[i] == b'x' { + c_x += 1; + } + } + } + + if x % 2 == 1 { + -1 + } else { + if c_x % 2 == 0 { + x / 2 + } else { + x / 2 + 1 + } + } + } +} diff --git a/src/bin/minimum-time-visiting-all-points.rs b/src/bin/minimum-time-visiting-all-points.rs new file mode 100644 index 00000000..2eaf1966 --- /dev/null +++ b/src/bin/minimum-time-visiting-all-points.rs @@ -0,0 +1,28 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() { + assert_eq!( + Solution::min_time_to_visit_all_points(vec![vec![1, 1], vec![3, 4], vec![-1, 0]]), + 7 + ); + + assert_eq!( + Solution::min_time_to_visit_all_points(vec![vec![3, 2], vec![-2, 2]]), + 5 + ); +} + +struct Solution; + +impl Solution { + pub fn min_time_to_visit_all_points(points: Vec>) -> i32 { + (1..points.len()) + .map(|x| Self::distance(&points[x - 1], &points[x])) + .sum() + } + + /// 实际就是x[0]-y[0]与x[1]-y[1]的最大值 + fn distance(x: &[i32], y: &[i32]) -> i32 { + (x[0] - y[0]).abs().max((x[1] - y[1]).abs()) + } +} diff --git a/src/bin/missing-number.rs b/src/bin/missing-number.rs new file mode 100644 index 00000000..4f54f502 --- /dev/null +++ b/src/bin/missing-number.rs @@ -0,0 +1,24 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + println!("{}", Solution::missing_number1(vec![3, 0, 1])); + println!( + "{}", + Solution::missing_number1(vec![9, 6, 4, 2, 3, 5, 7, 0, 1]) + ); +} + +struct Solution; + +impl Solution { + pub fn missing_number(nums: Vec) -> i32 { + (0..=nums.len() as i32).sum::() - nums.into_iter().sum::() + } + + pub fn missing_number1(nums: Vec) -> i32 { + let l = nums.len() as i32; + nums.into_iter() + .enumerate() + .fold(l, |l, (x, y)| x as i32 ^ y ^ l) + } +} diff --git a/src/bin/modify-the-matrix.rs b/src/bin/modify-the-matrix.rs new file mode 100644 index 00000000..5c277e51 --- /dev/null +++ b/src/bin/modify-the-matrix.rs @@ -0,0 +1,23 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn modified_matrix(matrix: Vec>) -> Vec> { + let mut matrix = matrix; + + for i in 0..matrix[0].len() { + let max = (0..matrix.len()).map(|x| matrix[x][i]).max().unwrap(); + + for j in 0..matrix.len() { + if matrix[j][i] == -1 { + matrix[j][i] = max; + } + } + } + + matrix + } +} diff --git a/src/bin/monotonic-array.rs b/src/bin/monotonic-array.rs new file mode 100644 index 00000000..cb3bc0d4 --- /dev/null +++ b/src/bin/monotonic-array.rs @@ -0,0 +1,60 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn is_monotonic1(a: Vec) -> bool { + if a.len() <= 1 { + return true; + } + + let mut f = None; + + for i in 1..a.len() { + if a[i] == a[i - 1] { + continue; + } + + if f.is_none() { + f = Some(a[i] > a[i - 1]); + } + if let Some(s) = f { + if s && a[i] < a[i - 1] { + return false; + } + + if !s && a[i] > a[i - 1] { + return false; + } + } + } + + true + } + + pub fn is_monotonic(a: Vec) -> bool { + if a.len() <= 1 { + return true; + } + + let mut s = 0; + + for i in 1..a.len() { + if a[i] == a[i - 1] { + continue; + } + + if s == 0 && a[i] - a[1] != 0 { + s = a[i] - a[i - 1]; + } + + if s * a[i] - a[i - 1] < 0 { + return false; + } + } + + true + } +} diff --git a/src/bin/most-frequent-subtree-sum.rs b/src/bin/most-frequent-subtree-sum.rs new file mode 100644 index 00000000..6dafdced --- /dev/null +++ b/src/bin/most-frequent-subtree-sum.rs @@ -0,0 +1,74 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +// Definition for a binary tree node. +#[derive(Debug, PartialEq, Eq)] +pub struct TreeNode { + pub val: i32, + pub left: Option>>, + pub right: Option>>, +} + +impl TreeNode { + #[inline] + pub fn new(val: i32) -> Self { + TreeNode { + val, + left: None, + right: None, + } + } +} + +use std::cell::RefCell; +use std::rc::Rc; + +impl Solution { + pub fn find_frequent_tree_sum(root: Option>>) -> Vec { + let mut root = root; + let mut h = std::collections::HashMap::new(); + let mut max = 0; + Self::get_sum(&mut root, &mut h, &mut max); + + h.iter() + .filter(|&(_, y)| *y == max) + .map(|(&x, _)| x) + .collect() + } + + fn get_sum( + root: &mut Option>>, + h: &mut std::collections::HashMap, + max: &mut i32, + ) { + if root.is_none() { + return; + } + + Self::get_sum(&mut root.as_mut().unwrap().borrow_mut().left, h, max); + Self::get_sum(&mut root.as_mut().unwrap().borrow_mut().right, h, max); + + let sum = root + .as_ref() + .unwrap() + .borrow() + .left + .as_ref() + .map_or(0, |x| x.borrow().val) + + root + .as_ref() + .unwrap() + .borrow() + .right + .as_ref() + .map_or(0, |x| x.borrow().val) + + root.as_ref().unwrap().borrow().val; + + root.as_mut().unwrap().borrow_mut().val = sum; + let count = h.entry(sum).and_modify(|x| *x += 1).or_insert(1); + *max = (*max).max(*count) + } +} diff --git a/src/bin/most-profit-assigning-work.rs b/src/bin/most-profit-assigning-work.rs new file mode 100644 index 00000000..963d454a --- /dev/null +++ b/src/bin/most-profit-assigning-work.rs @@ -0,0 +1,27 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn max_profit_assignment(difficulty: Vec, profit: Vec, worker: Vec) -> i32 { + let mut d: Vec<(i32, i32)> = difficulty.into_iter().zip(profit.into_iter()).collect(); + d.sort(); + let mut worker = worker; + worker.sort(); + let mut max = 0; + let mut result = 0; + let mut j = 0; + for i in worker { + while j < d.len() && d[j].0 <= i { + max = max.max(d[j].1); + j += 1; + } + + result += max; + } + + result + } +} diff --git a/src/bin/move-pieces-to-obtain-a-string.rs b/src/bin/move-pieces-to-obtain-a-string.rs new file mode 100644 index 00000000..b7901070 --- /dev/null +++ b/src/bin/move-pieces-to-obtain-a-string.rs @@ -0,0 +1,55 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn can_change(start: String, target: String) -> bool { + let (start, target) = (start.as_bytes(), target.as_bytes()); + let (mut i, mut j) = (0, 0); + + while i < start.len() && j < target.len() { + while i < start.len() && start[i] == b'_' { + i += 1; + } + + while j < target.len() && target[j] == b'_' { + j += 1; + } + + if i >= start.len() || j >= target.len() { + break; + } + + if start[i] != target[j] { + return false; + } + + match start[i] { + b'L' if i < j => return false, + b'R' if i > j => return false, + _ => { + i += 1; + j += 1; + } + } + } + + while i < start.len() { + if start[i] != b'_' { + return false; + } + i += 1; + } + + while j < target.len() { + if target[j] != b'_' { + return false; + } + j += 1; + } + + true + } +} diff --git a/src/bin/move-zeroes.rs b/src/bin/move-zeroes.rs new file mode 100644 index 00000000..12dc8ff9 --- /dev/null +++ b/src/bin/move-zeroes.rs @@ -0,0 +1,34 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + let mut v = vec![0, 1, 0, 3, 12]; + Solution::move_zeroes(&mut v); + println!("{:?}", v); +} + +struct Solution; + +impl Solution { + pub fn move_zeroes(nums: &mut Vec) { + let (mut i, mut j) = (0, 0); + + while j < nums.len() { + match (nums[i], nums[j]) { + (0, 0) => { + j += 1; + } + (_, 0) => { + j += 1; + } + (0, _) => { + nums.swap(i, j); + i += 1; + } + _ => { + i += 1; + j += 1; + } + } + } + } +} diff --git a/src/bin/movement-of-robots.rs b/src/bin/movement-of-robots.rs new file mode 100644 index 00000000..c0f76afc --- /dev/null +++ b/src/bin/movement-of-robots.rs @@ -0,0 +1,31 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn sum_distance(nums: Vec, s: String, d: i32) -> i32 { + let mut nums = nums; + let s = s.as_bytes(); + + for i in 0..s.len() { + if s[i] == b'R' { + nums[i] += d; + } else { + nums[i] -= d; + } + } + + nums.sort(); + let mut result = 0i64; + const MOD: i64 = 10i64.pow(9) + 7; + let mut sum = 0i64; + for i in 0..s.len() { + result = (result + nums[i] as i64 * i as i64 - sum) % MOD; + sum = (sum + nums[i] as i64) % MOD; + } + + result as i32 + } +} diff --git a/src/bin/multiply-strings.rs b/src/bin/multiply-strings.rs new file mode 100644 index 00000000..1a03dd86 --- /dev/null +++ b/src/bin/multiply-strings.rs @@ -0,0 +1,50 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + assert_eq!( + "6".to_string(), + Solution::multiply("2".to_string(), "3".to_string()) + ); + assert_eq!( + "56088".to_string(), + Solution::multiply("123".to_string(), "456".to_string()) + ); + assert_eq!( + "998001".to_string(), + Solution::multiply("999".to_string(), "999".to_string()) + ); + assert_eq!("30501687172287445993560048081057096686019986405658336826483685740920318317486606305094807387278589614".to_string(), Solution::multiply("60974249908865105026646412538664653190280198809433017".to_string(), "500238825698990292381312765074025160144624723742".to_string())); +} + +struct Solution; + +impl Solution { + pub fn multiply(num1: String, num2: String) -> String { + if &num1 == "0" || &num2 == "0" { + return "0".to_string(); + } + + let mut res = vec![0i32; num1.len() + num2.len()]; + + for (i1, &v1) in num1.as_bytes().iter().enumerate() { + for (i2, &v2) in num2.as_bytes().iter().enumerate() { + let s = (v1 - b'0') as i32 * (v2 - b'0') as i32; + res[i1 + i2 + 1] += s % 10; + res[i1 + i2] += s / 10; + } + } + + let mut s = vec!["-".to_string(); res.len()]; + let (mut i, len) = (0, res.len() - 1); + while i <= len { + if res[len - i] < 10 { + s[len - i] = res[len - i].to_string(); + } else { + s[len - i] = (res[len - i] % 10).to_string(); + res[len - i - 1] += res[len - i] / 10; + } + i += 1; + } + s.join("").trim_start_matches('0').to_string() + } +} diff --git a/src/bin/n-queens-ii.rs b/src/bin/n-queens-ii.rs new file mode 100644 index 00000000..d2e90b86 --- /dev/null +++ b/src/bin/n-queens-ii.rs @@ -0,0 +1,60 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + assert_eq!(92, Solution::total_n_queens(8)); +} + +struct Solution; + +impl Solution { + pub fn total_n_queens(n: i32) -> i32 { + let mut nums = vec![vec![b'.'; n as usize]; n as usize]; + let mut result = 0; + Self::find(&mut nums, n, &mut result); + result + } + + fn find(nums: &mut Vec>, n: i32, result: &mut i32) { + if n == 0 { + *result += 1; + return; + } + + let len = nums.len(); + + for j in 0..len { + if !Self::check(nums, len - n as usize, j) { + continue; + } + + nums[len - n as usize][j] = b'Q'; + Self::find(nums, n - 1, result); + nums[len - n as usize][j] = b'.'; + } + } + + /// 检查(i, j)在nums中是否满足不受攻击 + fn check(nums: &Vec>, i: usize, j: usize) -> bool { + let mut index = 1; + let len = nums.len(); + + while i >= index { + // 判断与(i, j)同列的是否为皇后 + if nums[i - index][j] == b'Q' { + return false; + } + + // 判断(i, j)的左上斜线是否为皇后 + if j >= index && nums[i - index][j - index] == b'Q' { + return false; + } + + // 判断(i, j)的右上斜线是否为皇后 + if j + index < len && nums[i - index][j + index] == b'Q' { + return false; + } + index += 1; + } + true + } +} diff --git a/src/bin/n-queens.rs b/src/bin/n-queens.rs new file mode 100644 index 00000000..411f3623 --- /dev/null +++ b/src/bin/n-queens.rs @@ -0,0 +1,69 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn solve_n_queens(n: i32) -> Vec> { + let mut r = Vec::>::new(); + let mut nums = vec![vec![b'.'; n as usize]; n as usize]; + Self::queen(&mut nums, n, &mut r); + r + } + + fn queen(nums: &mut Vec>, n: i32, r: &mut Vec>) { + if n == 0 { + let mut x = Vec::with_capacity(nums.len()); + + for i in nums.iter() { + x.push(String::from_utf8(i.clone()).unwrap()); + } + r.push(x); + return; + } + let len = nums.len(); + + for i in 0..len { + // 如果当前点不满足条件,检查下一个点 + if !Self::check(nums, len - n as usize, i) { + continue; + } + + nums[len - n as usize][i] = b'Q'; + Self::queen(nums, n - 1, r); + nums[len - n as usize][i] = b'.'; + } + } + + // 检查坐标(i,j)是否可以放置 + fn check(nums: &Vec>, i: usize, j: usize) -> bool { + let n2 = nums.len(); + + for index in 0..i { + // 检查同列 + if nums[index][j] == b'Q' { + return false; + } + } + + // 检查主对角线上方 + let mut offset = 1; + while i >= offset && j >= offset { + if nums[i - offset][j - offset] == b'Q' { + return false; + } + offset += 1; + } + // 检查副对角线上方 + let mut offset = 1; + while i >= offset && j + offset < n2 { + if nums[i - offset][j + offset] == b'Q' { + return false; + } + offset += 1; + } + + true + } +} diff --git a/src/bin/n-th-tribonacci-number.rs b/src/bin/n-th-tribonacci-number.rs new file mode 100644 index 00000000..4bb28f42 --- /dev/null +++ b/src/bin/n-th-tribonacci-number.rs @@ -0,0 +1,23 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn tribonacci(n: i32) -> i32 { + let mut a = [0, 1, 1]; + if n <= 2 { + return a[n as usize]; + } + + for i in 3..=n { + let old = a[0]; + a[0] = a[1]; + a[1] = a[2]; + a[2] = old + a[0] + a[1]; + } + + a[2] + } +} diff --git a/src/bin/nGK0Fy.rs b/src/bin/nGK0Fy.rs new file mode 100644 index 00000000..b3041960 --- /dev/null +++ b/src/bin/nGK0Fy.rs @@ -0,0 +1,20 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn calculate(s: String) -> i32 { + let (mut x, mut y) = (1, 0); + for i in s.bytes() { + match i { + b'A' => x = 2 * x + y, + b'B' => y = 2 * y + x, + _ => unreachable!(), + } + } + + x + y + } +} diff --git a/src/bin/na-ying-bi.rs b/src/bin/na-ying-bi.rs new file mode 100644 index 00000000..b7deeae3 --- /dev/null +++ b/src/bin/na-ying-bi.rs @@ -0,0 +1,13 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + assert_eq!(Solution::min_count(vec![4, 2, 1]), 4); +} + +struct Solution; + +impl Solution { + pub fn min_count(coins: Vec) -> i32 { + coins.into_iter().map(|x| x / 2 + x % 2).sum() + } +} diff --git a/src/bin/next-greater-node-in-linked-list.rs b/src/bin/next-greater-node-in-linked-list.rs new file mode 100644 index 00000000..ae100cd2 --- /dev/null +++ b/src/bin/next-greater-node-in-linked-list.rs @@ -0,0 +1,48 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +// Definition for singly-linked list. +#[derive(PartialEq, Eq, Clone, Debug)] +pub struct ListNode { + pub val: i32, + pub next: Option>, +} + +impl ListNode { + #[inline] + fn new(val: i32) -> Self { + ListNode { next: None, val } + } +} + +impl Solution { + pub fn next_larger_nodes(mut head: Option>) -> Vec { + let mut v = vec![]; + while let Some(l) = head.take() { + v.push(l.val); + head = l.next; + } + + let (mut stack, mut res) = (vec![], vec![0; v.len()]); + + for i in 0..v.len() { + if stack.len() == 0 { + stack.push(i); + } else { + while let Some(&t) = stack.last() { + if v[i] <= v[t] { + break; + } + res[stack.pop().unwrap()] = v[i]; + } + + stack.push(i); + } + } + + res + } +} diff --git a/src/bin/next-permutation.rs b/src/bin/next-permutation.rs new file mode 100644 index 00000000..2c31753c --- /dev/null +++ b/src/bin/next-permutation.rs @@ -0,0 +1,40 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + let mut v = vec![1, 2, 3]; + Solution::next_permutation(&mut v); + println!("{:?}", v); + + let mut v = vec![1, 3, 2]; + Solution::next_permutation(&mut v); + println!("{:?}", v); + + let mut v = vec![2, 3, 1]; + Solution::next_permutation(&mut v); + println!("{:?}", v); +} + +struct Solution; + +impl Solution { + // 遍历数组,找到最后一个处于峰顶的数字 + pub fn next_permutation(nums: &mut Vec) { + for i in (0..nums.len() - 1).rev() { + if nums[i] < nums[i + 1] { + let mut min = i + 1; + + for j in (i + 1..nums.len()).rev() { + if nums[j] > nums[i] && nums[min] > nums[j] { + min = j; + } + } + + nums.swap(i, min); + + nums[i + 1..].sort(); + return; + } + } + nums.sort(); + } +} diff --git a/src/bin/nge-tou-zi-de-dian-shu-lcof.rs b/src/bin/nge-tou-zi-de-dian-shu-lcof.rs new file mode 100644 index 00000000..0b652a4a --- /dev/null +++ b/src/bin/nge-tou-zi-de-dian-shu-lcof.rs @@ -0,0 +1,29 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +use std::vec; + +fn main() {} + +struct Solution; + +impl Solution { + /// 和的范围为n - 6n + pub fn dices_probability(n: i32) -> Vec { + if n == 1 { + return vec![1.0 / 6.0; 6]; + } + + let mut r = vec![0f64; (5 * n + 1) as usize]; + + let r1 = Self::dices_probability(n - 1); + + for i in 1..=6 { + // index代表n-1个骰子的和,index=0的和为n-1 + for (index, &value) in r1.iter().enumerate() { + r[(index + (n - 1) as usize) + i - n as usize] += value * 1.0 / 6.0; + } + } + + r + } +} diff --git a/src/bin/nim-game.rs b/src/bin/nim-game.rs new file mode 100644 index 00000000..977fcc3c --- /dev/null +++ b/src/bin/nim-game.rs @@ -0,0 +1,11 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn can_win_nim(n: i32) -> bool { + n % 4 != 0 + } +} diff --git a/src/bin/nth-digit.rs b/src/bin/nth-digit.rs new file mode 100644 index 00000000..7827d2c9 --- /dev/null +++ b/src/bin/nth-digit.rs @@ -0,0 +1,49 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + println!("{}", Solution::find_nth_digit(1)); + println!("{}", Solution::find_nth_digit(2)); + println!("{}", Solution::find_nth_digit(10)); + println!("{}", Solution::find_nth_digit(11)); + println!("{}", Solution::find_nth_digit(12)); + println!("{}", Solution::find_nth_digit(13)); + println!("{}", Solution::find_nth_digit(14)); + println!("{}", Solution::find_nth_digit(190)); + println!("{}", Solution::find_nth_digit(191)); + println!("{}", Solution::find_nth_digit(192)); + println!("{}", Solution::find_nth_digit(193)); + println!("{}", Solution::find_nth_digit(312313)); + println!("{}", Solution::find_nth_digit(1000000000)); +} + +struct Solution; + +impl Solution { + /// 1.先找到n代表的数字有几位,规律:数字每增加一位,个数为:1*9 + 20*9 + 300*9... + pub fn find_nth_digit(n: i32) -> i32 { + if n <= 9 { + return n; + } + + let mut n = n; + + let mut s: i32 = 1; // n所在的数字有几位 + + loop { + let m = 9i64 * s as i64 * 10i64.pow(s as u32 - 1) as i64; + if (n as i64) < m { + break; + } else { + n -= m as i32; + s += 1; + } + } + + // 基于相同位数的最小值的偏移,比如1123相对于1000偏移123 + let n1 = n - 1; + + let x = 10i32.pow(s as u32 - 1) + n1 / s; // 定位到具体的数字 + + x / 10i32.pow((s - n1 % s - 1) as u32) % 10 + } +} diff --git a/src/bin/number-complement.rs b/src/bin/number-complement.rs new file mode 100644 index 00000000..0b50d95e --- /dev/null +++ b/src/bin/number-complement.rs @@ -0,0 +1,17 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + // assert_eq!(2, Solution::find_complement(5)); + println!("{:#b}", Solution::find_complement(5)); + println!("{:#b}", Solution::find_complement(1)); + println!("{:#b}", Solution::find_complement(2)); +} + +struct Solution; + +impl Solution { + pub fn find_complement(num: i32) -> i32 { + let lz = num.leading_zeros(); + !num << lz >> lz + } +} diff --git a/src/bin/number-of-1-bits.rs b/src/bin/number-of-1-bits.rs new file mode 100644 index 00000000..12c3369c --- /dev/null +++ b/src/bin/number-of-1-bits.rs @@ -0,0 +1,20 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn hammingWeight(n: u32) -> i32 { + let mut r = 0; + let mut n = n; + while n > 0 { + if n % 2 == 1 { + r += 1; + } + n /= 2; + } + + r + } +} diff --git a/src/bin/number-of-arithmetic-triplets.rs b/src/bin/number-of-arithmetic-triplets.rs new file mode 100644 index 00000000..4821fbf0 --- /dev/null +++ b/src/bin/number-of-arithmetic-triplets.rs @@ -0,0 +1,20 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn arithmetic_triplets(nums: Vec, diff: i32) -> i32 { + let mut map: std::collections::HashSet = nums.iter().map(|x| *x).collect(); + let mut result = 0; + + for i in 0..nums.len() { + if map.contains(&(nums[i] + diff)) && map.contains(&(nums[i] + diff + diff)) { + result += 1; + } + } + + result + } +} diff --git a/src/bin/number-of-beautiful-pairs.rs b/src/bin/number-of-beautiful-pairs.rs new file mode 100644 index 00000000..4b25e6f6 --- /dev/null +++ b/src/bin/number-of-beautiful-pairs.rs @@ -0,0 +1,48 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() { + assert_eq!( + Solution::count_beautiful_pairs(vec![84, 91, 18, 59, 27, 9, 81, 33, 17, 58],), + 37 + ); +} + +struct Solution; + +impl Solution { + pub fn count_beautiful_pairs(nums: Vec) -> i32 { + let m = [ + [0; 10], + [0, 1, 1, 1, 1, 1, 1, 1, 1, 1], // 1 + [0, 1, 0, 1, 0, 1, 0, 1, 0, 1], // 2 + [0, 1, 1, 0, 1, 1, 0, 1, 1, 0], // 3 + [0, 1, 0, 1, 0, 1, 0, 1, 0, 1], // 4 + [0, 1, 1, 1, 1, 0, 1, 1, 1, 1], // 5 + [0, 1, 0, 0, 0, 1, 0, 1, 0, 0], // 6 + [0, 1, 1, 1, 1, 1, 1, 0, 1, 1], // 7 + [0, 1, 0, 1, 0, 1, 0, 1, 0, 1], // 8 + [0, 1, 1, 0, 1, 1, 0, 1, 1, 0], // 9 + ]; + + let f = |mut x: i32| -> i32 { + while x > 9 { + x /= 10; + } + x + }; + + let mut result = 0; + for i in 0..nums.len() { + for j in i + 1..nums.len() { + let x = (nums[j] % 10) as usize; + let y = f(nums[i]) as usize; + + if m[x][y] == 1 { + result += 1; + } + } + } + + result + } +} diff --git a/src/bin/number-of-boomerangs.rs b/src/bin/number-of-boomerangs.rs new file mode 100644 index 00000000..eb8bde4f --- /dev/null +++ b/src/bin/number-of-boomerangs.rs @@ -0,0 +1,46 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn number_of_boomerangs(points: Vec>) -> i32 { + if points.len() < 3 { + return 0; + } + + let mut x: std::collections::HashMap> = + std::collections::HashMap::new(); + + for i in 0..points.len() { + for j in 0..points.len() { + if i == j { + continue; + } + + let length = + (points[i][0] - points[j][0]).pow(2) + (points[i][1] - points[j][1]).pow(2); + + x.entry(i) + .and_modify(|m| { + m.entry(length).and_modify(|x| *x += 1).or_insert(1); + }) + .or_insert({ + let mut m = std::collections::HashMap::new(); + m.insert(length, 1); + m + }); + } + } + + let mut result = 0; + for v in x.values() { + for x in v.values() { + result += (1 + x - 1) * (x - 1); + } + } + + result + } +} diff --git a/src/bin/number-of-burgers-with-no-waste-of-ingredients.rs b/src/bin/number-of-burgers-with-no-waste-of-ingredients.rs new file mode 100644 index 00000000..aee2eca6 --- /dev/null +++ b/src/bin/number-of-burgers-with-no-waste-of-ingredients.rs @@ -0,0 +1,18 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn num_of_burgers(tomato_slices: i32, cheese_slices: i32) -> Vec { + let x = (tomato_slices - 2 * cheese_slices) / 2; + let y = (4 * cheese_slices - tomato_slices) / 2; + + if x < 0 || y < 0 || 4 * x + 2 * y != tomato_slices || x + y != cheese_slices { + vec![] + } else { + vec![x, y] + } + } +} diff --git a/src/bin/number-of-closed-islands.rs b/src/bin/number-of-closed-islands.rs new file mode 100644 index 00000000..0b5433d9 --- /dev/null +++ b/src/bin/number-of-closed-islands.rs @@ -0,0 +1,67 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + // 从四个边界开始寻找,找到陆地变成水 + // 然后再次遍历,为陆地的地方即为岛屿? + pub fn closed_island(mut grid: Vec>) -> i32 { + for i in 0..grid[0].len() { + Self::bfs((0, i), &mut grid); + } + + for i in 0..grid[0].len() { + Self::bfs((grid.len() - 1, i), &mut grid); + } + + for i in 0..grid.len() { + Self::bfs((i, 0), &mut grid); + } + + for i in 0..grid.len() { + Self::bfs((i, grid[0].len() - 1), &mut grid); + } + + let mut r = 0; + + for i in 0..grid.len() { + for j in 0..grid[0].len() { + if grid[i][j] == 0 { + r += 1; + Self::bfs((i, j), &mut grid); + } + } + } + + r + } + + fn bfs(start: (usize, usize), grid: &mut Vec>) { + if start.0 > grid.len() - 1 { + return; + } + + if start.1 > grid[0].len() - 1 { + return; + } + + if grid[start.0][start.1] == 1 { + return; + } else { + grid[start.0][start.1] = 1; + } + + if start.0 > 0 { + Self::bfs((start.0 - 1, start.1), grid); + } + + if start.1 > 0 { + Self::bfs((start.0, start.1 - 1), grid); + } + + Self::bfs((start.0 + 1, start.1), grid); + Self::bfs((start.0, start.1 + 1), grid); + } +} diff --git a/src/bin/number-of-common-factors.rs b/src/bin/number-of-common-factors.rs new file mode 100644 index 00000000..d82811d0 --- /dev/null +++ b/src/bin/number-of-common-factors.rs @@ -0,0 +1,13 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn common_factors(a: i32, b: i32) -> i32 { + (1..=a.min(b)) + .filter(|x| a % *x == 0 && b % *x == 0) + .count() as i32 + } +} diff --git a/src/bin/number-of-dice-rolls-with-target-sum.rs b/src/bin/number-of-dice-rolls-with-target-sum.rs new file mode 100644 index 00000000..fd52cf58 --- /dev/null +++ b/src/bin/number-of-dice-rolls-with-target-sum.rs @@ -0,0 +1,26 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn num_rolls_to_target(n: i32, k: i32, target: i32) -> i32 { + if target < n || target > n * k { + return 0; // 无法组成 target + } + const MOD: i32 = 1_000_000_007; + let (n, k, target) = (n as usize, k as usize, target as usize); + let mut f = vec![vec![0; target - n + 1]; n + 1]; + f[0][0] = 1; + for i in 1..=n { + for j in 0..=target - n { + for x in 0..k.min(j + 1) { + // 掷出了 x + f[i][j] = (f[i][j] + f[i - 1][j - x]) % MOD; + } + } + } + f[n][target - n] + } +} diff --git a/src/bin/number-of-employees-who-met-the-target.rs b/src/bin/number-of-employees-who-met-the-target.rs new file mode 100644 index 00000000..34d05191 --- /dev/null +++ b/src/bin/number-of-employees-who-met-the-target.rs @@ -0,0 +1,11 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn number_of_employees_who_met_target(hours: Vec, target: i32) -> i32 { + hours.into_iter().filter(|x| *x >= target).count() as i32 + } +} diff --git a/src/bin/number-of-good-pairs.rs b/src/bin/number-of-good-pairs.rs new file mode 100644 index 00000000..e856a867 --- /dev/null +++ b/src/bin/number-of-good-pairs.rs @@ -0,0 +1,20 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn num_identical_pairs(nums: Vec) -> i32 { + let mut hash = std::collections::HashMap::new(); + let mut result = 0; + for i in nums { + if let Some(&x) = hash.get(&i) { + result += x; + } + + hash.entry(i).and_modify(|x| *x += 1).or_insert(1); + } + result + } +} diff --git a/src/bin/number-of-islands.rs b/src/bin/number-of-islands.rs new file mode 100644 index 00000000..3e51bbe8 --- /dev/null +++ b/src/bin/number-of-islands.rs @@ -0,0 +1,46 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn num_islands(grid: Vec>) -> i32 { + let mut grid = grid; + let mut r = 0; + + for i in 0..grid.len() { + for j in 0..grid[0].len() { + if grid[i][j] == '1' { + r += 1; + Self::change_1_to_0(&mut grid, (i, j)); + } + } + } + + r + } + + fn change_1_to_0(grid: &mut Vec>, index: (usize, usize)) { + if index.0 == grid.len() || index.1 == grid[0].len() { + return; + } + + if grid[index.0][index.1] == '0' { + return; + } + + grid[index.0][index.1] = '0'; + + Self::change_1_to_0(grid, (index.0 + 1, index.1)); + Self::change_1_to_0(grid, (index.0, index.1 + 1)); + + if index.0 > 0 { + Self::change_1_to_0(grid, (index.0 - 1, index.1)); + } + + if index.1 > 0 { + Self::change_1_to_0(grid, (index.0, index.1 - 1)); + } + } +} diff --git a/src/bin/number-of-segments-in-a-string.rs b/src/bin/number-of-segments-in-a-string.rs new file mode 100644 index 00000000..7994b0e8 --- /dev/null +++ b/src/bin/number-of-segments-in-a-string.rs @@ -0,0 +1,29 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn count_segments(s: String) -> i32 { + if s == "".to_string() { + return 0; + } + + let mut num = 0; + let mut flag = true; + + for i in s.chars().into_iter() { + if flag && i != ' ' { + num += 1; + flag = false; + } + + if i == ' ' { + flag = true; + } + } + + num + } +} diff --git a/src/bin/number-of-senior-citizens.rs b/src/bin/number-of-senior-citizens.rs new file mode 100644 index 00000000..a205e640 --- /dev/null +++ b/src/bin/number-of-senior-citizens.rs @@ -0,0 +1,14 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn count_seniors(details: Vec) -> i32 { + details + .iter() + .filter(|x| &x.as_str()[11..=12] > "60") + .count() as i32 + } +} diff --git a/src/bin/number-of-smooth-descent-periods-of-a-stock.rs b/src/bin/number-of-smooth-descent-periods-of-a-stock.rs new file mode 100644 index 00000000..2844d5b0 --- /dev/null +++ b/src/bin/number-of-smooth-descent-periods-of-a-stock.rs @@ -0,0 +1,25 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn get_descent_periods(prices: Vec) -> i64 { + let mut r = 0; + let mut current = prices[0]; + let mut current_num = 1; + + for i in 1..prices.len() { + if current - 1 == prices[i] { + current_num += 1; + } else { + r += (current_num + 1) * current_num / 2; + current_num = 1; + } + current = prices[i]; + } + r += (current_num + 1) * current_num / 2; + r + } +} diff --git a/src/bin/number-of-substrings-with-only-1s.rs b/src/bin/number-of-substrings-with-only-1s.rs new file mode 100644 index 00000000..801702c5 --- /dev/null +++ b/src/bin/number-of-substrings-with-only-1s.rs @@ -0,0 +1,26 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn num_sub(s: String) -> i32 { + let mut n = 0i64; + let mut r = 0i64; + for &i in s.as_bytes() { + match i { + b'0' => { + r += (1 + n) * n / 2 % (1000000000 + 7); + n = 0; + } + b'1' => n += 1, + _ => unreachable!(), + } + } + + r += (1 + n) * n / 2 % (1000000000 + 7); + + r as i32 + } +} diff --git a/src/bin/number-of-times-binary-string-is-prefix-aligned.rs b/src/bin/number-of-times-binary-string-is-prefix-aligned.rs new file mode 100644 index 00000000..d60ac465 --- /dev/null +++ b/src/bin/number-of-times-binary-string-is-prefix-aligned.rs @@ -0,0 +1,21 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn num_times_all_blue(flips: Vec) -> i32 { + let mut ans = 0; + let mut right = 0; + + for (i, v) in flips.into_iter().enumerate() { + right = right.max(v as i32); + if i as i32 + 1 == right { + ans += 1; + } + } + + ans + } +} diff --git a/src/bin/number-of-unequal-triplets-in-array.rs b/src/bin/number-of-unequal-triplets-in-array.rs new file mode 100644 index 00000000..79cb58fa --- /dev/null +++ b/src/bin/number-of-unequal-triplets-in-array.rs @@ -0,0 +1,28 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn unequal_triplets(nums: Vec) -> i32 { + let mut h = std::collections::HashMap::new(); + let n = nums.len() as i32; + for i in nums { + h.entry(i).and_modify(|x| *x += 1).or_insert(1); + } + + let mut ans = 0; + let mut x = 0; + // 当前元素的个数为v + // 当前元素前面的元素个数为x + // 当前元素后面的个数为n-x-v + // 则当前元素为中间元素可以组成 x * v * (n - v - x) 个数 + for (_, v) in h.into_iter() { + ans += x * v * (n - v - x); + x += v; + } + + ans + } +} diff --git a/src/bin/number-of-ways-to-buy-pens-and-pencils.rs b/src/bin/number-of-ways-to-buy-pens-and-pencils.rs new file mode 100644 index 00000000..58e160ed --- /dev/null +++ b/src/bin/number-of-ways-to-buy-pens-and-pencils.rs @@ -0,0 +1,25 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn ways_to_buy_pens_pencils(total: i32, cost1: i32, cost2: i32) -> i64 { + let (max, min) = if cost1 > cost2 { + (cost1 as i64, cost2 as i64) + } else { + (cost2 as i64, cost1 as i64) + }; + + let mut r = 0; + let mut i = 0; + + while i * max <= total as i64 { + r += (total as i64 - max * i) / min + 1; + i += 1; + } + + r + } +} diff --git a/src/bin/numbers-with-same-consecutive-differences.rs b/src/bin/numbers-with-same-consecutive-differences.rs new file mode 100644 index 00000000..8e37b4a6 --- /dev/null +++ b/src/bin/numbers-with-same-consecutive-differences.rs @@ -0,0 +1,35 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn nums_same_consec_diff(n: i32, k: i32) -> Vec { + let mut v = vec![]; + for i in 1..=9 { + let mut stack = vec![]; + stack.push(i.to_string()); + while let Some(elem) = stack.pop() { + if elem.len() == n as usize { + v.push(elem.parse::().unwrap()); + } else { + let s = elem.as_str()[elem.len() - 1..].parse::().unwrap(); + if s + k < 10 { + let mut e = elem.clone(); + e.push_str((s + k).to_string().as_str()); + stack.push(e); + } + + if k != 0 && s - k >= 0 { + let mut e = elem.clone(); + e.push_str((s - k).to_string().as_str()); + stack.push(e); + } + } + } + } + + v + } +} diff --git a/src/bin/occurrences-after-bigram.rs b/src/bin/occurrences-after-bigram.rs new file mode 100644 index 00000000..8d886927 --- /dev/null +++ b/src/bin/occurrences-after-bigram.rs @@ -0,0 +1,24 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn find_ocurrences(text: String, first: String, second: String) -> Vec { + let mut result = vec![]; + let mut n = text.split(' '); + let mut f = n.next().unwrap(); + let mut is_result = false; + while let Some(x) = n.next() { + if is_result { + result.push(x.to_string()); + } + + is_result = f == first && x == second; + f = x; + } + + result + } +} diff --git a/src/bin/odd-string-difference.rs b/src/bin/odd-string-difference.rs new file mode 100644 index 00000000..ec2a2bc4 --- /dev/null +++ b/src/bin/odd-string-difference.rs @@ -0,0 +1,28 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn odd_string(words: Vec) -> String { + let mut d = std::collections::HashMap::new(); + + for i in words { + let mut s = vec![]; + for j in 1..i.as_bytes().len() { + s.push(i.as_bytes()[j] - i.as_bytes()[j - 1]); + } + + d.entry(s).or_insert(vec![]).push(i); + } + + for (i, j) in d { + if j.len() == 1 { + return j[0].clone(); + } + } + + unreachable!() + } +} diff --git a/src/bin/online-election.rs b/src/bin/online-election.rs new file mode 100644 index 00000000..296ec617 --- /dev/null +++ b/src/bin/online-election.rs @@ -0,0 +1,90 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + let s = TopVotedCandidate::new(vec![0, 1, 1, 0, 0, 1, 0], vec![0, 5, 10, 15, 20, 25, 30]); + assert_eq!(s.q(3), 0); + assert_eq!(s.q(12), 1); + assert_eq!(s.q(25), 1); + assert_eq!(s.q(15), 0); + assert_eq!(s.q(24), 0); + assert_eq!(s.q(8), 1); + + let s = TopVotedCandidate::new(vec![0, 0, 0, 0, 1], vec![0, 6, 39, 52, 75]); + assert_eq!(s.q(45), 0); + assert_eq!(s.q(49), 0); + assert_eq!(s.q(59), 0); + assert_eq!(s.q(68), 0); + assert_eq!(s.q(42), 0); + assert_eq!(s.q(37), 0); + assert_eq!(s.q(99), 0); + assert_eq!(s.q(26), 0); + assert_eq!(s.q(78), 0); + assert_eq!(s.q(43), 0); +} + +/** + * Your TopVotedCandidate object will be instantiated and called as such: + * let obj = TopVotedCandidate::new(persons, times); + * let ret_1: i32 = obj.q(t); + */ +struct TopVotedCandidate { + count: Vec, + times: Vec, +} + +/** + * `&self` means the method takes an immutable reference. + * If you need a mutable reference, change it to `&mut self` instead. + */ +impl TopVotedCandidate { + fn new(persons: Vec, times: Vec) -> Self { + Self { + count: Self::build(persons), + times, + } + } + + fn q(&self, t: i32) -> i32 { + let (mut start, mut end) = (0usize, self.times.len() - 1); + let mut middle = (start + end) / 2; + // binary search + while start < end { + if self.times[middle] == t || middle == 0 || middle == self.times.len() - 1 { + break; + } else if self.times[middle] > t && self.times[middle - 1] < t { + middle -= 1; + break; + } else if self.times[middle] < t && self.times[middle + 1] > t { + break; + } else if self.times[middle] > t { + end = middle; + middle = (start + end) / 2; + } else { + start = middle + 1; + middle = (start + end) / 2; + } + } + + self.count[middle] + } + + fn build(persons: Vec) -> Vec { + let mut v = Vec::with_capacity(persons.len()); + let mut counts = std::collections::HashMap::new(); + let mut max_count = 0; + let mut max_value = 0; + + for i in persons { + let c = counts.entry(i).and_modify(|x| *x += 1).or_insert(1); + if *c >= max_count { + v.push(i); + max_value = i; + max_count = *c; + } else { + v.push(max_value); + } + } + + v + } +} diff --git a/src/bin/online-stock-span.rs b/src/bin/online-stock-span.rs new file mode 100644 index 00000000..4ec3ea74 --- /dev/null +++ b/src/bin/online-stock-span.rs @@ -0,0 +1,40 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +struct StockSpanner { + n: i32, + stack: Vec<(i32, i32)>, +} + +/** + * `&self` means the method takes an immutable reference. + * If you need a mutable reference, change it to `&mut self` instead. + */ +/** + * Your StockSpanner object will be instantiated and called as such: + * let obj = StockSpanner::new(); + * let ret_1: i32 = obj.next(price); + */ +impl StockSpanner { + fn new() -> Self { + Self { + n: -1, + stack: vec![(-1, i32::MAX)], + } + } + + fn next(&mut self, price: i32) -> i32 { + self.n += 1; + + while !self.stack.is_empty() && price >= self.stack[self.stack.len() - 1].1 { + self.stack.pop(); + } + + self.stack.push((self.n, price)); + + self.n - self.stack[self.stack.len() - 2].0 + } +} diff --git a/src/bin/opLdQZ.rs b/src/bin/opLdQZ.rs new file mode 100644 index 00000000..9108e8b2 --- /dev/null +++ b/src/bin/opLdQZ.rs @@ -0,0 +1,52 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +// Definition for a binary tree node. +#[derive(Debug, PartialEq, Eq)] +pub struct TreeNode { + pub val: i32, + pub left: Option>>, + pub right: Option>>, +} + +impl TreeNode { + #[inline] + pub fn new(val: i32) -> Self { + TreeNode { + val, + left: None, + right: None, + } + } +} +use std::cell::RefCell; +use std::rc::Rc; +impl Solution { + pub fn find_target(root: Option>>, k: i32) -> bool { + let mut hash = std::collections::HashMap::new(); + Self::f(root, &mut hash, k) + } + + pub fn f( + root: Option>>, + hash: &mut std::collections::HashMap, + k: i32, + ) -> bool { + if root.is_none() { + return false; + } + let val = root.clone().unwrap().borrow().val; + if hash.contains_key(&(k - val)) { + return true; + } + + hash.insert(val, ()); + let left = root.clone().unwrap().borrow().left.clone(); + let right = root.clone().unwrap().borrow().right.clone(); + + Self::f(left, hash, k) || Self::f(right, hash, k) + } +} diff --git a/src/bin/operations-on-tree.rs b/src/bin/operations-on-tree.rs new file mode 100644 index 00000000..9db63991 --- /dev/null +++ b/src/bin/operations-on-tree.rs @@ -0,0 +1,107 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +struct LockingTree { + children: std::collections::HashMap>, + parents: std::collections::HashMap, + /// node: user_id + locked: std::collections::HashMap, +} + +/** + * `&self` means the method takes an immutable reference. + * If you need a mutable reference, change it to `&mut self` instead. + */ + +/** + * Your LockingTree object will be instantiated and called as such: + * let obj = LockingTree::new(parent); + * let ret_1: bool = obj.lock(num, user); + * let ret_2: bool = obj.unlock(num, user); + * let ret_3: bool = obj.upgrade(num, user); + */ + +impl LockingTree { + fn new(parent: Vec) -> Self { + let mut children = std::collections::HashMap::>::new(); + let mut parents = std::collections::HashMap::new(); + for i in 0..parent.len() { + children + .entry(parent[i]) + .and_modify(|x| x.push(i as _)) + .or_insert(vec![i as _]); + + parents.insert(i as _, parent[i]); + } + + Self { + children, + parents, + locked: std::collections::HashMap::new(), + } + } + + fn lock(&mut self, num: i32, user: i32) -> bool { + if self.locked.contains_key(&num) { + return false; + } + + self.locked.insert(num, user); + true + } + + fn unlock(&mut self, num: i32, user: i32) -> bool { + match self.locked.get(&num) { + Some(&x) if x == user => {} + _ => return false, + } + + self.locked.remove(&num); + true + } + + fn upgrade(&mut self, num: i32, user: i32) -> bool { + if self.locked.contains_key(&num) { + return false; + } + + if self.check_parent(num) { + return false; + } + + if !self.unlock_sons(num) { + return false; + } + + self.locked.insert(num, user); + true + } + + /// 解锁子孙。如果有一个子孙已加锁,返回true。 + fn unlock_sons(&mut self, num: i32) -> bool { + let len = if let Some(x) = self.children.get(&num) { + x.len() + } else { + return false; + }; + + let mut result = false; + for i in 0..len { + result |= self.locked.remove(&self.children[&num][i]).is_some(); + result |= self.unlock_sons(self.children[&num][i]); + } + + result + } + + /// 检查父节点,如果都是未加锁,返回true + fn check_parent(&self, num: i32) -> bool { + match self.parents.get(&num) { + Some(&x) => self.locked.contains_key(&x) || self.check_parent(x), + None => false, + } + } +} diff --git a/src/bin/p0NxJO.rs b/src/bin/p0NxJO.rs new file mode 100644 index 00000000..1e8c241e --- /dev/null +++ b/src/bin/p0NxJO.rs @@ -0,0 +1,42 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + /// 使用heap保存前面出现的负数,然后记录所有的血量之和,当血量为负数时,说明到此位置的生时候需要调整。 + /// 我们弹出heap中血量最小的(也就是减去血量最多的),然后放到末尾,这时血量之和应该把此血量减去的加上,如果为正数,停止调整。 + pub fn magic_tower(nums: Vec) -> i32 { + use std::cmp::Reverse; + + let mut heap = std::collections::BinaryHeap::new(); + let mut total = 1i64; // 初始血量为1 + let mut num = 0; + let mut total_sum = 0i64; + for i in nums { + total_sum += i as i64; + if i < 0 { + heap.push(Reverse(i)); + } + + total += i as i64; + + if total <= 0 { + while let Some(Reverse(x)) = heap.pop() { + num += 1; + total += -x as i64; + if total > 0 { + break; + } + } + } + } + + if total_sum >= 0 { + num + } else { + -1 + } + } +} diff --git a/src/bin/pOCWxh.rs b/src/bin/pOCWxh.rs new file mode 100644 index 00000000..67a19625 --- /dev/null +++ b/src/bin/pOCWxh.rs @@ -0,0 +1,46 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +// Definition for a binary tree node. +#[derive(Debug, PartialEq, Eq)] +pub struct TreeNode { + pub val: i32, + pub left: Option>>, + pub right: Option>>, +} + +impl TreeNode { + #[inline] + pub fn new(val: i32) -> Self { + TreeNode { + val, + left: None, + right: None, + } + } +} + +use std::cell::RefCell; +use std::rc::Rc; +impl Solution { + pub fn prune_tree(root: Option>>) -> Option>> { + if root.is_none() { + return None; + } + + let left = Self::prune_tree(root.clone().unwrap().borrow_mut().left.take()); + let right = Self::prune_tree(root.clone().unwrap().borrow_mut().right.take()); + + if left.is_none() && right.is_none() && root.clone().unwrap().borrow().val == 0 { + return None; + } + + root.clone().unwrap().borrow_mut().left = left; + root.clone().unwrap().borrow_mut().right = right; + + root + } +} diff --git a/src/bin/palindrome-linked-list.rs b/src/bin/palindrome-linked-list.rs new file mode 100644 index 00000000..036600a1 --- /dev/null +++ b/src/bin/palindrome-linked-list.rs @@ -0,0 +1,42 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +// Definition for singly-linked list. +#[derive(PartialEq, Eq, Clone, Debug)] +pub struct ListNode { + pub val: i32, + pub next: Option>, +} + +impl ListNode { + #[inline] + fn new(val: i32) -> Self { + ListNode { next: None, val } + } +} + +impl Solution { + pub fn is_palindrome(head: Option>) -> bool { + let mut v = vec![]; + let mut head = head; + + while head.is_some() { + v.push(head.as_ref().unwrap().val); + head = head.as_mut().unwrap().next.take(); + } + + let (mut star, mut end) = (0, v.len() - 1); + while star < end { + if v[star] != v[end] { + return false; + } + star += 1; + end -= 1; + } + + true + } +} diff --git a/src/bin/palindrome-number.rs b/src/bin/palindrome-number.rs new file mode 100644 index 00000000..e3e70d82 --- /dev/null +++ b/src/bin/palindrome-number.rs @@ -0,0 +1,59 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + /// 常规解法,将数字转化为字符串,然后挨个比较 + pub fn is_palindrome1(x: i32) -> bool { + if x < 0 { + return false; + } + + if x < 10 { + return true; + } + + let s = x.to_string().into_bytes(); + let (mut i1, mut i2) = (0, s.len() - 1); + + while i1 < i2 { + if s[i1] != s[i2] { + return false; + } + i1 += 1; + i2 -= 1; + } + + true + } + ///第二个想法是将数字本身反转,然后将反转后的数字与原始数字进行比较,如果它们是相同的,那么这个数字就是回文。 + /// 但是,如果反转后的数字大于 \text{int.MAX}int.MAX,我们将遇到整数溢出问题。 + /// + /// 按照第二个想法,为了避免数字反转可能导致的溢出问题,为什么不考虑只反转 \text{int}int 数字的一半?毕竟,如果该数字是回文,其后半部分反转后应该与原始数字的前半部分相同。 + /// + /// 例如,输入 1221,我们可以将数字 “1221” 的后半部分从 “21” 反转为 “12”,并将其与前半部分 “12” 进行比较,因为二者相同,我们得知数字 1221 是回文。 + pub fn is_palindrome(x: i32) -> bool { + // 所有小于10的都是 + if x < 10 && x >= 0 { + return true; + } + + // 所有个位数有0的,即可以被10整除的都不是,例如1110 + if x < 0 || x % 10 == 0 { + return false; + } + + let mut x = x; + let mut r = 0; + + while x > r { + r = x % 10 + r * 10; + x /= 10; + } + + // 数字为12321时,r 为123, x为12,因此r要处以10 + x == r || r / 10 == x + } +} diff --git a/src/bin/palindromic-substrings.rs b/src/bin/palindromic-substrings.rs new file mode 100644 index 00000000..4b9a68e3 --- /dev/null +++ b/src/bin/palindromic-substrings.rs @@ -0,0 +1,41 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() { + assert_eq!(Solution::count_substrings("abc".into()), 3); + assert_eq!(Solution::count_substrings("aaa".into()), 6); +} + +struct Solution; + +impl Solution { + /// 设f(i, j)表示是否s[i..j]为回文串(包含j) + /// f(i, j) = f(i+1, j-1) && s[i] == s[j] + pub fn count_substrings(s: String) -> i32 { + let s = s.as_bytes(); + let mut dp = vec![vec![false; s.len()]; s.len()]; + let mut ans = 0; + + // 从长度为2开始遍历 + for sub_string_length in 0..s.len() { + for j in 0..s.len() { + if j + sub_string_length > s.len() - 1 { + break; + } + + if sub_string_length == 0 { + dp[j][j + sub_string_length] = true; + } else if sub_string_length == 1 { + dp[j][j + sub_string_length] = s[j] == s[j + sub_string_length]; + } else { + dp[j][j + sub_string_length] = + dp[j + 1][j + sub_string_length - 1] && s[j] == s[j + sub_string_length]; + } + + if dp[j][j + sub_string_length] { + ans += 1; + } + } + } + ans + } +} diff --git a/src/bin/partition-list.rs b/src/bin/partition-list.rs new file mode 100644 index 00000000..2508965f --- /dev/null +++ b/src/bin/partition-list.rs @@ -0,0 +1,44 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +// Definition for singly-linked list. +#[derive(PartialEq, Eq, Clone, Debug)] +pub struct ListNode { + pub val: i32, + pub next: Option>, +} + +impl ListNode { + #[inline] + fn new(val: i32) -> Self { + ListNode { next: None, val } + } +} +impl Solution { + pub fn partition(head: Option>, x: i32) -> Option> { + let (mut l1, mut l2) = (ListNode::new(-1), ListNode::new(-1)); + let (mut ptr1, mut ptr2) = (&mut l1.next, &mut l2.next); + + let mut head = head; + + while head.is_some() { + let mut h = head.unwrap(); + head = h.next.take(); + + if h.val < x { + *ptr1 = Some(h); + ptr1 = ptr1.as_mut().map(|mut x| &mut x.next).unwrap(); + } else { + *ptr2 = Some(h); + ptr2 = ptr2.as_mut().map(|mut x| &mut x.next).unwrap(); + } + } + + *ptr1 = l2.next.take(); + + l1.next + } +} diff --git a/src/bin/partitioning-into-minimum-number-of-deci-binary-numbers.rs b/src/bin/partitioning-into-minimum-number-of-deci-binary-numbers.rs new file mode 100644 index 00000000..73769a56 --- /dev/null +++ b/src/bin/partitioning-into-minimum-number-of-deci-binary-numbers.rs @@ -0,0 +1,39 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + //实际可以分解为: + // 最大位那一列全是1,其他的补0或者1 + // 例如:82734 + // 第一列全是1 + // 第二列2两个1,其余都是0 + // 第三列7个1,其余是0 + // 第四列3个1,其余是0 + // 第五列4个1,其余是0 + // + // 1 1 1 1 1 + // 1 1 1 1 1 + // 1 0 1 1 1 + // 1 0 1 0 1 + // 1 0 1 0 0 + // 1 0 1 0 0 + // 1 0 1 0 0 + // 1 0 0 0 0 + // + // 这样就可以看作找最大位是哪一个数,因此遍历字符串,需要最大数就行了。 + pub fn min_partitions(n: String) -> i32 { + let mut max = b'0'; + + for &i in n.as_bytes().into_iter() { + max = max.max(i); + if max == b'9' { + break; + } + } + + (max - b'0') as i32 + } +} diff --git a/src/bin/pascals-triangle-ii.rs b/src/bin/pascals-triangle-ii.rs new file mode 100644 index 00000000..f920994c --- /dev/null +++ b/src/bin/pascals-triangle-ii.rs @@ -0,0 +1,24 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + println!("{:?}", Solution::get_row(6)); +} + +struct Solution; + +impl Solution { + pub fn get_row(row_index: i32) -> Vec { + let mut v = vec![0; row_index as usize + 1]; + + for i in 0..row_index + 1 { + v[i as usize] = 1; + let mut x = v[0]; + for j in 1..i { + let y = v[j as usize]; + v[j as usize] += x; + x = y; + } + } + v + } +} diff --git a/src/bin/pascals-triangle.rs b/src/bin/pascals-triangle.rs new file mode 100644 index 00000000..2b10e60f --- /dev/null +++ b/src/bin/pascals-triangle.rs @@ -0,0 +1,28 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn generate(num_rows: i32) -> Vec> { + let mut result: Vec> = Vec::with_capacity(num_rows as usize); + + for i in 1..=num_rows { + let mut r = Vec::with_capacity(i as usize); + for j in 0..i { + if j == 0 || j == i - 1 { + r.push(1); + } else { + r.push( + result[i as usize - 2][j as usize - 1] + result[i as usize - 2][j as usize], + ); + } + } + + result.push(r); + } + + result + } +} diff --git a/src/bin/pass-the-pillow.rs b/src/bin/pass-the-pillow.rs new file mode 100644 index 00000000..b663e327 --- /dev/null +++ b/src/bin/pass-the-pillow.rs @@ -0,0 +1,16 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn pass_the_pillow(n: i32, time: i32) -> i32 { + let time = time % ((n - 1) * 2); + if time < n { + time + 1 + } else { + n * 2 - time - 1 + } + } +} diff --git a/src/bin/path-sum-ii.rs b/src/bin/path-sum-ii.rs new file mode 100644 index 00000000..c5079545 --- /dev/null +++ b/src/bin/path-sum-ii.rs @@ -0,0 +1,75 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +// Definition for a binary tree node. +#[derive(Debug, PartialEq, Eq)] +pub struct TreeNode { + pub val: i32, + pub left: Option>>, + pub right: Option>>, +} + +impl TreeNode { + #[inline] + pub fn new(val: i32) -> Self { + TreeNode { + val, + left: None, + right: None, + } + } +} + +use std::cell::RefCell; +use std::rc::Rc; + +impl Solution { + pub fn path_sum(root: Option>>, target_sum: i32) -> Vec> { + match Self::f(root, target_sum) { + Some(x) => x, + None => vec![], + } + } + + fn f(root: Option>>, target_sum: i32) -> Option>> { + if root.is_none() { + return None; + } + + let value = root.as_ref().unwrap().borrow().val; + let left = root.as_ref().unwrap().borrow_mut().left.take(); + let right = root.as_ref().unwrap().borrow_mut().right.take(); + + if target_sum - value == 0 { + if left.is_none() && right.is_none() { + return Some(vec![vec![value]]); + } + } + + let mut left = match Self::f(left, target_sum - value) { + Some(mut x) => { + x.iter_mut().for_each(|x| x.insert(0, value)); + x + } + None => vec![], + }; + + let mut right = match Self::f(right, target_sum - value) { + Some(mut x) => { + x.iter_mut().for_each(|x| x.insert(0, value)); + x + } + None => vec![], + }; + + right.append(&mut left); + if right.len() == 0 { + None + } else { + Some(right) + } + } +} diff --git a/src/bin/path-sum-iii.rs b/src/bin/path-sum-iii.rs new file mode 100644 index 00000000..16f58d4f --- /dev/null +++ b/src/bin/path-sum-iii.rs @@ -0,0 +1,70 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +use std::cell::RefCell; +use std::rc::Rc; + +fn main() {} + +struct Solution; + +// Definition for a binary tree node. +#[derive(Debug, PartialEq, Eq)] +pub struct TreeNode { + pub val: i32, + pub left: Option>>, + pub right: Option>>, +} + +impl TreeNode { + #[inline] + pub fn new(val: i32) -> Self { + TreeNode { + val, + left: None, + right: None, + } + } +} + +impl Solution { + pub fn path_sum(root: Option>>, target_sum: i32) -> i32 { + if root.is_none() { + return 0; + } + let mut result = 0; + + let mut stack = vec![root]; + while let Some(x) = stack.pop() { + let left = x.clone().unwrap().borrow().left.clone(); + if left.is_some() { + stack.push(left); + } + + let right = x.clone().unwrap().borrow().right.clone(); + if right.is_some() { + stack.push(right); + } + + Self::dfs(x, target_sum as i64, 0, &mut result); + } + + result + } + + fn dfs(root: Option>>, target_sum: i64, current: i64, result: &mut i32) { + if root.is_none() { + return; + } + + let v = root.clone().unwrap().borrow().val as i64; + if v + current == target_sum { + *result += 1; + } + + let left = root.clone().unwrap().borrow().left.clone(); + let right = root.clone().unwrap().borrow().right.clone(); + + Self::dfs(left, target_sum, current + v, result); + Self::dfs(right, target_sum, current + v, result); + } +} diff --git a/src/bin/path-sum.rs b/src/bin/path-sum.rs new file mode 100644 index 00000000..44051722 --- /dev/null +++ b/src/bin/path-sum.rs @@ -0,0 +1,45 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +// Definition for a binary tree node. +#[derive(Debug, PartialEq, Eq)] +pub struct TreeNode { + pub val: i32, + pub left: Option>>, + pub right: Option>>, +} + +impl TreeNode { + #[inline] + pub fn new(val: i32) -> Self { + TreeNode { + val, + left: None, + right: None, + } + } +} + +use std::cell::RefCell; +use std::rc::Rc; + +impl Solution { + pub fn has_path_sum(root: Option>>, target_sum: i32) -> bool { + if let Some(r) = root { + let value = Rc::clone(&r).borrow().val; + let left = Rc::clone(&r).borrow_mut().left.take(); + let right = Rc::clone(&r).borrow_mut().right.take(); + + if left.is_none() && right.is_none() && value == target_sum { + return true; + } + + return Self::has_path_sum(left, target_sum - value) + || Self::has_path_sum(right, target_sum - value); + } + false + } +} diff --git a/src/bin/perfect-number.rs b/src/bin/perfect-number.rs new file mode 100644 index 00000000..5218e012 --- /dev/null +++ b/src/bin/perfect-number.rs @@ -0,0 +1,11 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn check_perfect_number(num: i32) -> bool { + num == (1..=num / 2).into_iter().filter(|&x| num % x == 0).sum() + } +} diff --git a/src/bin/perfect-squares.rs b/src/bin/perfect-squares.rs new file mode 100644 index 00000000..44325cf6 --- /dev/null +++ b/src/bin/perfect-squares.rs @@ -0,0 +1,42 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + println!("{}", Solution::num_squares(12)); + println!("{}", Solution::num_squares(13)); +} + +struct Solution; + +impl Solution { + pub fn num_squares(n: i32) -> i32 { + let mut h = std::collections::HashMap::new(); + Self::f(n, &mut h) + } + + fn f(n: i32, h: &mut std::collections::HashMap) -> i32 { + if n == 0 { + return 0; + } + + if let Some(&x) = h.get(&n) { + return x; + } + + let mut s = 0; + + let mut m = 1; + while m * m <= n { + let s1 = 1 + Self::f(n - m * m, h); + if s == 0 { + s = s1; + } else { + s = s.min(s1) + } + m += 1; + } + + h.insert(n, s); + + s + } +} diff --git a/src/bin/permutation-difference-between-two-strings.rs b/src/bin/permutation-difference-between-two-strings.rs new file mode 100644 index 00000000..e493a642 --- /dev/null +++ b/src/bin/permutation-difference-between-two-strings.rs @@ -0,0 +1,23 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn find_permutation_difference(s: String, t: String) -> i32 { + let mut map = [0; 26]; + + for (i, v) in s.bytes().enumerate() { + map[(v - b'a') as usize] = i; + } + + let mut result = 0; + + for (i, v) in t.bytes().enumerate() { + result += (i as i32 - map[(v - b'a') as usize] as i32).abs(); + } + + result + } +} diff --git a/src/bin/permutations.rs b/src/bin/permutations.rs new file mode 100644 index 00000000..15e99b6a --- /dev/null +++ b/src/bin/permutations.rs @@ -0,0 +1,41 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn permute(nums: Vec) -> Vec> { + if nums.len() == 0 { + return vec![]; + } + + if nums.len() == 1 { + return vec![nums]; + } + let mut result = Vec::with_capacity(Self::factorial(nums.len())); + for i in 0..nums.len() { + let mut v = Vec::with_capacity(nums.len() - 1); + v.extend_from_slice(&nums[..i]); + v.extend_from_slice(&nums[i + 1..]); + let r = Self::permute(v); + + for j in r.into_iter() { + let mut s = Vec::with_capacity(nums.len() - 1); + s.push(nums[i]); + s.extend_from_slice(&j); + result.push(s); + } + } + + result + } + + fn factorial(x: usize) -> usize { + if x == 1 { + return 1usize; + } + + x * Self::factorial(x - 1) + } +} diff --git a/src/bin/ping-heng-er-cha-shu-lcof.rs b/src/bin/ping-heng-er-cha-shu-lcof.rs new file mode 100644 index 00000000..3f8def9d --- /dev/null +++ b/src/bin/ping-heng-er-cha-shu-lcof.rs @@ -0,0 +1,56 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +// Definition for a binary tree node. +#[derive(Debug, PartialEq, Eq)] +pub struct TreeNode { + pub val: i32, + pub left: Option>>, + pub right: Option>>, +} + +impl TreeNode { + #[inline] + pub fn new(val: i32) -> Self { + TreeNode { + val, + left: None, + right: None, + } + } +} +use std::cell::RefCell; +use std::rc::Rc; +impl Solution { + pub fn is_balanced(root: Option>>) -> bool { + Self::scan(root) != -1 + } + + pub fn scan(root: Option>>) -> i32 { + if root.is_none() { + return 0; + } + let root = root.clone().unwrap(); + let left = root.borrow_mut().left.take(); + let right = root.borrow_mut().right.take(); + + let h1 = Self::scan(left); + if h1 == -1 { + return -1; + } + + let h2 = Self::scan(right); + if h2 == -1 { + return -1; + } + + if (h1 - h2).abs() > 1 { + return -1; + } + + 1 + h1.max(h2) + } +} diff --git a/src/bin/plus-one.rs b/src/bin/plus-one.rs new file mode 100644 index 00000000..0c5bf075 --- /dev/null +++ b/src/bin/plus-one.rs @@ -0,0 +1,38 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + println!("{:?}", Solution::plus_one(vec![1])); + println!("{:?}", Solution::plus_one(vec![9])); + println!("{:?}", Solution::plus_one(vec![9, 9])); + println!("{:?}", Solution::plus_one(vec![1, 9])); + println!("{:?}", Solution::plus_one(vec![1, 9, 9])); + println!("{:?}", Solution::plus_one(vec![1, 2, 3])); + println!("{:?}", Solution::plus_one(vec![4, 3, 2, 1])); + println!("{:?}", Solution::plus_one(vec![0])); +} + +struct Solution; + +impl Solution { + pub fn plus_one(digits: Vec) -> Vec { + let mut digits = digits; + let l = digits.len() - 1; + // 当最后一位不为9时 + if digits[l] != 9 { + digits[l] += 1; + } else { + for i in (0..=l).rev() { + if digits[i] != 9 { + digits[i] += 1; + break; + } + digits[i] = 0; + if i == 0 { + digits[i] += 1; + digits.push(0); + } + } + } + digits + } +} diff --git a/src/bin/positions-of-large-groups.rs b/src/bin/positions-of-large-groups.rs new file mode 100644 index 00000000..7c1a62c5 --- /dev/null +++ b/src/bin/positions-of-large-groups.rs @@ -0,0 +1,52 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + assert_eq!( + vec![vec![3, 6]], + Solution::large_group_positions("abbxxxxzzy".to_string()) + ); + assert_eq!( + Vec::>::new(), + Solution::large_group_positions("abc".to_string()) + ); + assert_eq!( + vec![vec![3, 5], vec![6, 9], vec![12, 14]], + Solution::large_group_positions("abcdddeeeeaabbbcd".to_string()) + ); + assert_eq!( + vec![vec![0, 2]], + Solution::large_group_positions("aaa".to_string()) + ); +} + +struct Solution; + +impl Solution { + pub fn large_group_positions(s: String) -> Vec> { + let mut v = Vec::>::new(); + let s = s.as_bytes(); + let mut start = 0usize; + let mut end = 0usize; + + for (index, &value) in s.iter().enumerate() { + if index == 0 { + continue; + } + + if value == s[index - 1] { + end = index; + if end != s.len() - 1 { + continue; + } + } + + if end - start >= 2 { + v.push(vec![start as i32, end as i32]); + } + start = index; + end = index; + } + + v + } +} diff --git a/src/bin/power-of-three.rs b/src/bin/power-of-three.rs new file mode 100644 index 00000000..a07af5c1 --- /dev/null +++ b/src/bin/power-of-three.rs @@ -0,0 +1,21 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn is_power_of_three(n: i32) -> bool { + let mut n = n; + + while n > 1 || n < -1 { + if n % 3 == 0 { + n /= 3; + } else { + return false; + } + } + + n == 1 + } +} diff --git a/src/bin/power-of-two.rs b/src/bin/power-of-two.rs new file mode 100644 index 00000000..576e9d56 --- /dev/null +++ b/src/bin/power-of-two.rs @@ -0,0 +1,16 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + println!("{}", Solution::is_power_of_two(16)); + println!("{}", Solution::is_power_of_two(15)); + println!("{}", Solution::is_power_of_two(14)); + println!("{}", Solution::is_power_of_two(5)); +} + +struct Solution; + +impl Solution { + pub fn is_power_of_two(n: i32) -> bool { + n > 0 && (n - 1) & n == 0 + } +} diff --git a/src/bin/powerful-integers.rs b/src/bin/powerful-integers.rs new file mode 100644 index 00000000..85c3fc78 --- /dev/null +++ b/src/bin/powerful-integers.rs @@ -0,0 +1,32 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +use std::vec; + +fn main() {} + +struct Solution; + +impl Solution { + pub fn powerful_integers(x: i32, y: i32, bound: i32) -> Vec { + let mut result = std::collections::HashSet::new(); + let mut i = 0; + + while x.pow(i) <= bound { + let mut j = 0; + while x.pow(i) + y.pow(j) <= bound { + result.insert(x.pow(i) + y.pow(j)); + if y == 1 { + break; + } + j += 1; + } + i += 1; + + if x == 1 { + break; + } + } + + result.into_iter().collect() + } +} diff --git a/src/bin/powx-n.rs b/src/bin/powx-n.rs new file mode 100644 index 00000000..1fc5fdfa --- /dev/null +++ b/src/bin/powx-n.rs @@ -0,0 +1,52 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + println!("{}", Solution::my_pow(0.00001, 2147483647)); + println!("{}", Solution::my_pow(2.00000, 10)); + println!("{}", Solution::my_pow(2.00000, /**/ -2)); + println!("{}", Solution::my_pow(2.00000, -2147483648)); +} + +struct Solution; + +impl Solution { + pub fn my_pow(x: f64, n: i32) -> f64 { + if x == 0f64 { + return 0f64; + } + + if n == 0 { + return 1f64; + } + + let mut n = n; + + let flag = n < 0; + let mut result = x; + let mut n1 = 2i32; + let s = n == std::i32::MIN; + if s { + n += 1; + } + + while n.abs() > 1 { + result *= result; + let n2 = n1.overflowing_mul(2); + if n2.1 || n2.0 > n.abs() { + result *= Self::my_pow(x, n.abs() - n1); + break; + } + n1 = n2.0; + } + + if s { + result *= x + } + + if flag { + 1f64 / result + } else { + result + } + } +} diff --git a/src/bin/predict-the-winner.rs b/src/bin/predict-the-winner.rs new file mode 100644 index 00000000..9a7559d8 --- /dev/null +++ b/src/bin/predict-the-winner.rs @@ -0,0 +1,25 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn predict_the_winner(nums: Vec) -> bool { + let mut dp = vec![vec![0; nums.len()]; nums.len()]; + + for i in 0..nums.len() { + dp[i][i] = nums[i]; + } + + if nums.len() > 1 { + for i in (0..=nums.len() - 2).rev() { + for j in i + 1..nums.len() { + dp[i][j] = (nums[i] - dp[i + 1][j]).max(nums[j] - dp[i][j - 1]); + } + } + } + + dp[0][nums.len() - 1] >= 0 + } +} diff --git a/src/bin/product-of-array-except-self.rs b/src/bin/product-of-array-except-self.rs new file mode 100644 index 00000000..09617877 --- /dev/null +++ b/src/bin/product-of-array-except-self.rs @@ -0,0 +1,47 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + println!("{:?}", Solution::product_except_self(vec![1, 2, 3, 4])); +} + +struct Solution; + +impl Solution { + /// 常规解法 + pub fn product_except_self1(nums: Vec) -> Vec { + let sum = nums.iter().fold(1, |x, y| x * *y); + + nums.iter().fold(vec![], |mut x, y| { + x.push(sum / (*y)); + x + }) + } + + /// 左右乘积,某个位置的积 == 左边*右边 + pub fn product_except_self(nums: Vec) -> Vec { + let mut v = Vec::with_capacity(nums.len()); + for i in 0..nums.len() { + if i == 0 { + v.push(1); + } else if i == 1 { + v.push(nums[i - 1]); + } else { + v.push(nums[i - 1] * v[i - 1]); + } + } + + let mut x = 1; + + for i in (0..nums.len()).rev() { + if i == nums.len() - 1 { + x = nums[i]; + continue; + } else { + v[i] = v[i] * x; + x *= nums[i]; + } + } + + v + } +} diff --git a/src/bin/pseudo-palindromic-paths-in-a-binary-tree.rs b/src/bin/pseudo-palindromic-paths-in-a-binary-tree.rs new file mode 100644 index 00000000..d5118c06 --- /dev/null +++ b/src/bin/pseudo-palindromic-paths-in-a-binary-tree.rs @@ -0,0 +1,61 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +use std::cell::RefCell; +use std::rc::Rc; + +fn main() {} + +struct Solution; + +// Definition for a binary tree node. +#[derive(Debug, PartialEq, Eq)] +pub struct TreeNode { + pub val: i32, + pub left: Option>>, + pub right: Option>>, +} + +impl TreeNode { + #[inline] + pub fn new(val: i32) -> Self { + TreeNode { + val, + left: None, + right: None, + } + } +} + +impl Solution { + pub fn pseudo_palindromic_paths(root: Option>>) -> i32 { + let mut map = [0; 10]; + Self::dfs(root, &mut map) + } + + fn dfs(root: Option>>, map: &mut [u8]) -> i32 { + if root.is_none() { + return 0; + } + + let root = root.unwrap(); + let root_val = root.borrow().val; + let left = root.borrow_mut().left.take(); + let right = root.borrow_mut().right.take(); + + map[(root_val - 0) as usize] += 1; + + let value = if left.is_none() && right.is_none() { + if map.iter().filter(|x| **x % 2 == 1).count() > 1 { + 0 + } else { + 1 + } + } else { + Self::dfs(left, map) + Self::dfs(right, map) + }; + + map[(root_val - 0) as usize] -= 1; + + value + } +} diff --git a/src/bin/push-dominoes.rs b/src/bin/push-dominoes.rs new file mode 100644 index 00000000..4f89fbce --- /dev/null +++ b/src/bin/push-dominoes.rs @@ -0,0 +1,51 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + println!("{}", Solution::push_dominoes(".L.R...LR..L..".to_string())); +} + +struct Solution; + +impl Solution { + pub fn push_dominoes(dominoes: String) -> String { + let mut s = dominoes.into_bytes(); + + let mut slow = 0; + + for i in 0..s.len() { + if s[i] == b'.' && i != s.len() - 1 { + continue; + } + + let mut fast = i; + if s[slow] != b'R' && s[fast] == b'L' { + while fast > slow { + if s[slow] == b'.' { + s[slow] = b'L'; + } + slow += 1; + } + } else if s[slow] == b'R' && s[fast] == b'L' { + while fast > slow { + s[fast] = b'L'; + s[slow] = b'R'; + fast -= 1; + slow += 1; + } + } else if s[slow] == b'R' && (s[fast] == b'R' || fast == s.len() - 1) { + while fast >= slow { + if s[slow] == b'.' { + s[slow] = b'R'; + } + + slow += 1; + } + } else if s[slow] == b'R' && s[fast] == b'R' { + } + + slow = i; + } + + unsafe { String::from_utf8_unchecked(s) } + } +} diff --git a/src/bin/qIsx9U.rs b/src/bin/qIsx9U.rs new file mode 100644 index 00000000..6ead6d30 --- /dev/null +++ b/src/bin/qIsx9U.rs @@ -0,0 +1,45 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +struct MovingAverage { + v: Vec, + len: f64, + index: usize, + sum: f64, +} + +/** + * `&self` means the method takes an immutable reference. + * If you need a mutable reference, change it to `&mut self` instead. + */ +impl MovingAverage { + /** Initialize your data structure here. */ + fn new(size: i32) -> Self { + Self { + v: vec![0f64; size as usize], + len: 0f64, + index: 0, + sum: 0f64, + } + } + + fn next(&mut self, val: i32) -> f64 { + self.sum += val as f64; + self.sum -= self.v[self.index]; + self.v[self.index] = val as f64; + self.index += 1; + + if self.len < self.v.len() as f64 { + self.len += 1f64; + } + + if self.index >= self.v.len() { + self.index = 0; + } + + self.sum / self.len as f64 + } +} diff --git a/src/bin/qing-wa-tiao-tai-jie-wen-ti-lcof.rs b/src/bin/qing-wa-tiao-tai-jie-wen-ti-lcof.rs new file mode 100644 index 00000000..821b5550 --- /dev/null +++ b/src/bin/qing-wa-tiao-tai-jie-wen-ti-lcof.rs @@ -0,0 +1,50 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + println!("{}", Solution::num_ways(2)); + println!("{}", Solution::num_ways(7)); + println!("{}", Solution::num_ways(0)); +} + +struct Solution; + +impl Solution { + pub fn num_ways1(n: i32) -> i32 { + let mut v = vec![0; n as usize + 1]; + Self::calc(n, &mut v); + *v.last().unwrap() + } + + fn calc(n: i32, map: &mut [i32]) { + if n <= 1 { + map[n as usize] = 1; + return; + } + + if map[n as usize - 1] == 0 { + Solution::calc(n - 1, map); + } + + if map[n as usize - 2] == 0 { + Solution::calc(n - 2, map); + } + + map[n as usize] = (map[n as usize - 1] + map[n as usize - 2]) % 1000000007; + } + + pub fn num_ways(n: i32) -> i32 { + if n <= 1 { + return 1; + } + + let (mut a, mut b) = (1, 1); + + for _ in 2..=n { + let x = (a + b) % 1000000007; + a = b; + b = x; + } + + b + } +} diff --git a/src/bin/qiu-12n-lcof.rs b/src/bin/qiu-12n-lcof.rs new file mode 100644 index 00000000..b44976bd --- /dev/null +++ b/src/bin/qiu-12n-lcof.rs @@ -0,0 +1,17 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn sum_nums(n: i32) -> i32 { + let mut n = n; + // 利用布尔短路的思想,n == 0 时,不会允许&&后面的表达式 + if n > 0 { + n += Self::sum_nums(n - 1); + } + + n + } +} diff --git a/src/bin/que-shi-de-shu-zi-lcof.rs b/src/bin/que-shi-de-shu-zi-lcof.rs new file mode 100644 index 00000000..ea96da2d --- /dev/null +++ b/src/bin/que-shi-de-shu-zi-lcof.rs @@ -0,0 +1,22 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn missing_number(nums: Vec) -> i32 { + let (mut start, mut end) = (0, nums.len()); + + while start < end { + let middle = (start + end) / 2; + if nums[middle] <= middle as i32 { + start = middle + 1; + } else { + end = middle; + } + } + + start as i32 + } +} diff --git a/src/bin/queens-that-can-attack-the-king.rs b/src/bin/queens-that-can-attack-the-king.rs new file mode 100644 index 00000000..9050cb84 --- /dev/null +++ b/src/bin/queens-that-can-attack-the-king.rs @@ -0,0 +1,97 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +use std::collections::HashSet; + +use serde::de::Unexpected::Option; +use tera::Filter; + +fn main() {} + +struct Solution; + +impl Solution { + pub fn queens_attackthe_king(queens: Vec>, king: Vec) -> Vec> { + use std::collections::HashSet; + let hash: HashSet<_> = queens.into_iter().collect(); + + // 枚举8个方向,遇到的第一个就行 + let mut result = vec![]; + let mut s = king[0]; + while s >= 1 { + if hash.contains(&vec![s - 1, king[1]]) { + result.push(vec![s - 1, king[1]]); + break; + } + s -= 1; + } + + let mut s = king[0]; + while s <= 6 { + if hash.contains(&vec![s + 1, king[1]]) { + result.push(vec![s + 1, king[1]]); + break; + } + s += 1; + } + + let mut s = king[1]; + while s >= 1 { + if hash.contains(&vec![king[0], s - 1]) { + result.push(vec![king[0], s - 1]); + break; + } + s -= 1; + } + + let mut s = king[1]; + while s <= 6 { + if hash.contains(&vec![king[0], s + 1]) { + result.push(vec![king[0], s + 1]); + break; + } + s += 1; + } + + let (mut s1, mut s2) = (king[0], king[1]); + while s1 >= 1 && s2 >= 1 { + if hash.contains(&vec![s1 - 1, s2 - 1]) { + result.push(vec![s1 - 1, s2 - 1]); + break; + } + s1 -= 1; + s2 -= 1; + } + + let (mut s1, mut s2) = (king[0], king[1]); + while s1 <= 6 && s2 <= 6 { + if hash.contains(&vec![s1 + 1, s2 + 1]) { + result.push(vec![s1 + 1, s2 + 1]); + break; + } + s1 += 1; + s2 += 1; + } + + let (mut s1, mut s2) = (king[0], king[1]); + while s1 >= 0 && s2 <= 6 { + if hash.contains(&vec![s1 - 1, s2 + 1]) { + result.push(vec![s1 - 1, s2 + 1]); + break; + } + s1 -= 1; + s2 += 1; + } + + let (mut s1, mut s2) = (king[0], king[1]); + while s1 <= 6 && s2 >= 0 { + if hash.contains(&vec![s1 + 1, s2 - 1]) { + result.push(vec![s1 + 1, s2 - 1]); + break; + } + s1 += 1; + s2 -= 1; + } + + result + } +} diff --git a/src/bin/queue-reconstruction-by-height.rs b/src/bin/queue-reconstruction-by-height.rs new file mode 100644 index 00000000..dbef04f4 --- /dev/null +++ b/src/bin/queue-reconstruction-by-height.rs @@ -0,0 +1,59 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() { + assert_eq!( + Solution::reconstruct_queue(vec![ + vec![7, 0], + vec![4, 4], + vec![7, 1], + vec![5, 0], + vec![6, 1], + vec![5, 2] + ]), + vec![ + vec![5, 0], + vec![7, 0], + vec![5, 2], + vec![6, 1], + vec![4, 4], + vec![7, 1] + ] + ) +} + +struct Solution; + +impl Solution { + /// 对于最矮的人来说,前面有n个人就说明他的位置是n+1 + /// 因此先按小到大排序,遍历已经寻找到为止的数组 + /// 当出现空位置或者出现高于的人,说明前面可以放一定数量的人。 + pub fn reconstruct_queue(people: Vec>) -> Vec> { + let mut people = people; + let mut v = vec![vec![]; people.len()]; + people.sort(); + + for i in people { + let mut k = i[1]; + let mut index = 0; + + while index < v.len() - 1 { + if v[index].is_empty() { + if k == 0 { + break; + } + k -= 1; + } else { + if v[index][0] >= i[0] { + k -= 1; + } + } + + index += 1; + } + + v[index] = i; + } + + v + } +} diff --git a/src/bin/random-pick-index.rs b/src/bin/random-pick-index.rs new file mode 100644 index 00000000..408047b6 --- /dev/null +++ b/src/bin/random-pick-index.rs @@ -0,0 +1,67 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +/** + * Your Solution object will be instantiated and called as such: + * let obj = Solution::new(nums); + * let ret_1: i32 = obj.pick(target); + */ +struct Solution1 { + index_map: std::collections::HashMap>, +} + +/** + * `&self` means the method takes an immutable reference. + * If you need a mutable reference, change it to `&mut self` instead. + */ +impl Solution1 { + fn new(nums: Vec) -> Self { + let mut index_map = std::collections::HashMap::new(); + + nums.into_iter().enumerate().for_each(|(index, value)| { + index_map + .entry(value) + .and_modify(|y: &mut Vec| y.push(index)) + .or_insert(vec![index]); + }); + + Self { index_map } + } + + fn pick(&self, target: i32) -> i32 { + use rand::Rng; + + match self.index_map.get(&target) { + Some(x) => x[rand::thread_rng().gen_range(0..x.len())] as i32, + None => 0, + } + } +} + +struct Solution { + nums: Vec, +} + +impl Solution { + fn new(nums: Vec) -> Self { + Self { nums } + } + + fn pick(&self, target: i32) -> i32 { + use rand::Rng; + let mut n = 0; + let mut r = 0; + + for i in 0..self.nums.len() { + if self.nums[i] == target { + n += 1; + if rand::thread_rng().gen_range(0..n) == 0 { + r = i as i32; + } + } + } + + r + } +} diff --git a/src/bin/range-sum-of-bst.rs b/src/bin/range-sum-of-bst.rs new file mode 100644 index 00000000..6491145f --- /dev/null +++ b/src/bin/range-sum-of-bst.rs @@ -0,0 +1,51 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +use std::cell::RefCell; +use std::rc::Rc; + +fn main() {} + +struct Solution; + +// Definition for a binary tree node. +#[derive(Debug, PartialEq, Eq)] +pub struct TreeNode { + pub val: i32, + pub left: Option>>, + pub right: Option>>, +} + +impl TreeNode { + #[inline] + pub fn new(val: i32) -> Self { + TreeNode { + val, + left: None, + right: None, + } + } +} + +impl Solution { + pub fn range_sum_bst(root: Option>>, low: i32, high: i32) -> i32 { + let mut result = 0; + + fn dfs(root: Option>>, result: &mut i32, low: i32, high: i32) { + if root.is_none() { + return; + } + + let root = root.unwrap(); + dfs(root.borrow_mut().left.take(), result, low, high); + dfs(root.borrow_mut().right.take(), result, low, high); + + if root.borrow().val <= high && root.borrow().val >= low { + *result += root.borrow().val; + } + } + + dfs(root, &mut result, low, high); + + result + } +} diff --git a/src/bin/range-sum-query-immutable.rs b/src/bin/range-sum-query-immutable.rs new file mode 100644 index 00000000..e75f65f1 --- /dev/null +++ b/src/bin/range-sum-query-immutable.rs @@ -0,0 +1,42 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +/** + * Your NumArray object will be instantiated and called as such: + * let obj = NumArray::new(nums); + * let ret_1: i32 = obj.sum_range(left, right); + */ +struct NumArray { + sums: Vec, +} + +/** + * `&self` means the method takes an immutable reference. + * If you need a mutable reference, change it to `&mut self` instead. + */ +impl NumArray { + fn new(nums: Vec) -> Self { + let mut sums = Vec::with_capacity(nums.len()); + + for i in 0..=nums.len() { + if i == 0 { + sums.push(0); + } else { + sums.push(nums[i] + sums[i - 1]); + } + } + + Self { sums } + } + + fn sum_range(&self, left: i32, right: i32) -> i32 { + if left == 0 { + self.sums[right as usize] + } else { + self.sums[right as usize] - self.sums[left as usize - 1usize] + } + } +} diff --git a/src/bin/range-sum-query-mutable.rs b/src/bin/range-sum-query-mutable.rs new file mode 100644 index 00000000..a968c3fb --- /dev/null +++ b/src/bin/range-sum-query-mutable.rs @@ -0,0 +1,104 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +use std::ptr::NonNull; + +fn main() {} + +struct Solution; + +struct NumArray { + nums: Vec, + segment_tree: Vec, +} + +/** + * `&self` means the method takes an immutable reference. + * If you need a mutable reference, change it to `&mut self` instead. + */ +/** + * Your NumArray object will be instantiated and called as such: + * let obj = NumArray::new(nums); + * obj.update(index, val); + * let ret_2: i32 = obj.sum_range(left, right); + */ +impl NumArray { + fn new(nums: Vec) -> Self { + let mut segment_tree = vec![0; nums.len() * 4]; + let mut num_array = Self { nums, segment_tree }; + + num_array.build(0, 0, num_array.nums.len() - 1); + num_array + } + + fn build(&mut self, tree_index: usize, l: usize, r: usize) { + if l == r { + self.segment_tree[tree_index] = self.nums[l]; + return; + } + + let left_tree_index = tree_index * 2 + 1; + let right_tree_index = tree_index * 2 + 2; + + let mid = l + (r - l) / 2; + self.build(left_tree_index, l, mid); + self.build(right_tree_index, mid + 1, r); + + self.segment_tree[tree_index] = + self.segment_tree[left_tree_index] + self.segment_tree[right_tree_index]; + } + + fn update(&mut self, index: i32, val: i32) { + let v = val - self.nums[index as usize]; + self.nums[index as usize] = val; + self.update_index(0, 0, self.nums.len() - 1, index as usize, v); + } + + fn update_index( + &mut self, + tree_index: usize, + left_index: usize, + right_index: usize, + index: usize, + val: i32, + ) { + self.segment_tree[tree_index] += val; + if left_index == right_index { + return; + } + + let mid = left_index + (right_index - left_index) / 2; + if index <= mid { + self.update_index(tree_index * 2 + 1, left_index, mid, index, val); + } else { + self.update_index(tree_index * 2 + 2, mid + 1, right_index, index, val); + } + } + + fn sum_range(&self, left: i32, right: i32) -> i32 { + self.get_range(0, 0, self.nums.len() - 1, left as usize, right as usize) + } + + /// tree_index: 线段树的索引 + /// l: tree_index表示的左边界 + /// r: tree_index表示的右边界 + /// left: 查询的左边界 + /// right: 查询的右边界 + fn get_range(&self, tree_index: usize, l: usize, r: usize, left: usize, right: usize) -> i32 { + if left == l && right == r { + return self.segment_tree[tree_index]; + } + + let mid = l + (r - l) / 2; + let left_tree_index = tree_index * 2 + 1; + let right_tree_index = tree_index * 2 + 2; + + if left > mid { + return self.get_range(right_tree_index, mid + 1, r, left, right); + } else if right <= mid { + return self.get_range(left_tree_index, l, mid, left, right); + } else { + self.get_range(left_tree_index, l, mid, left, mid) + + self.get_range(right_tree_index, mid + 1, r, mid + 1, right) + } + } +} diff --git a/src/bin/ransom-note.rs b/src/bin/ransom-note.rs new file mode 100644 index 00000000..7b7aa244 --- /dev/null +++ b/src/bin/ransom-note.rs @@ -0,0 +1,27 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn can_construct(ransom_note: String, magazine: String) -> bool { + let mut h = std::collections::HashMap::new(); + for i in magazine.bytes() { + h.entry(i).and_modify(|x| *x += 1).or_insert(1); + } + + for i in ransom_note.bytes() { + if let Some(x) = h.get_mut(&i) { + if *x >= 1 { + *x -= 1; + continue; + } + } + + return false; + } + + true + } +} diff --git a/src/bin/reconstruct-a-2-row-binary-matrix.rs b/src/bin/reconstruct-a-2-row-binary-matrix.rs new file mode 100644 index 00000000..17805cf9 --- /dev/null +++ b/src/bin/reconstruct-a-2-row-binary-matrix.rs @@ -0,0 +1,56 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn reconstruct_matrix(upper: i32, lower: i32, colsum: Vec) -> Vec> { + if colsum.iter().sum::() != upper + lower { + return Vec::>::new(); + } + + let mut v = vec![ + Vec::::with_capacity(colsum.len()), + Vec::::with_capacity(colsum.len()), + ]; + let mut v1_sum = 0; //第一个vec的和 + let mut v2_sum = 0; //第二个vec的和 + + // 当colsum为2时,都加1, + // 当colsum为1时,先都加给v[0] + for i in colsum.into_iter() { + if i == 2 { + v[0].push(1); + v[1].push(1); + v1_sum += 1; + v2_sum += 1; + } else if i == 0 { + v[0].push(0); + v[1].push(0); + } else { + v[0].push(1); + v[1].push(0); + v1_sum += 1; + } + } + + for i in 0..v[0].len() { + if v1_sum == upper { + break; + } + + if v[0][i] == 1 && v[1][i] == 0 { + v[0][i] = 0; + v[1][i] = 1; + v1_sum -= 1; + } + } + + if v1_sum != upper && v2_sum != lower { + return vec![]; + } + + v + } +} diff --git a/src/bin/reconstruct-original-digits-from-english.rs b/src/bin/reconstruct-original-digits-from-english.rs new file mode 100644 index 00000000..5c81a4f6 --- /dev/null +++ b/src/bin/reconstruct-original-digits-from-english.rs @@ -0,0 +1,69 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + assert_eq!( + "012".to_string(), + Solution::original_digits("owoztneoer".to_string()) + ); + assert_eq!( + "0123456789".to_string(), + Solution::original_digits("zeroonetwothreefourfivesixseveneightnine".to_string()) + ); +} + +struct Solution; + +impl Solution { + // zero + // one + // two + // three + // four + // five + // six + // seven + // eight + // nine + // efghinorstuvwxz + pub fn original_digits(s: String) -> String { + let mut l = [0; 26]; + let mut count = [0; 10]; // 用于记录每个数字的出现次数 + for &i in s.as_bytes().iter() { + l[(i - 97) as usize] += 1; + } + + let mut s = String::new(); + + for &i in "zwuxghfsin".as_bytes().iter() { + if i == b'z' { + count[0] += l[(i - 97) as usize] + } else if i == b'w' { + count[2] += l[(i - 97) as usize] + } else if i == b'u' { + count[4] += l[(i - 97) as usize] + } else if i == b'x' { + count[6] += l[(i - 97) as usize] + } else if i == b'g' { + count[8] += l[(i - 97) as usize] + } else if i == b'h' { + count[3] += l[(i - 97) as usize] - count[8] // 三的数量是h的数量剪掉8的数量 + } else if i == b'f' { + count[5] += l[(i - 97) as usize] - count[4] + } else if i == b's' { + count[7] += l[(i - 97) as usize] - count[6] + } else if i == b'i' { + count[9] += l[(i - 97) as usize] - count[6] - count[5] - count[8] + } else if i == b'n' { + count[1] += l[(i - 97) as usize] - count[7] - count[9] * 2 // 因为nine是两个n + } + } + + for (i, &v) in count.iter().enumerate() { + if v != 0 { + s.push_str(i.to_string().repeat(v).as_str()); + } + } + + s + } +} diff --git a/src/bin/rectangle-area.rs b/src/bin/rectangle-area.rs new file mode 100644 index 00000000..bfe0f137 --- /dev/null +++ b/src/bin/rectangle-area.rs @@ -0,0 +1,29 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn compute_area( + ax1: i32, + ay1: i32, + ax2: i32, + ay2: i32, + bx1: i32, + by1: i32, + bx2: i32, + by2: i32, + ) -> i32 { + let mut s = (ax2 - ax1) * (ay2 - ay1) + (bx2 - bx1) * (by2 - by1); + + let (px1, py1) = (bx1.max(ax1), by1.max(ay1)); + let (px2, py2) = (bx2.min(ax2), by2.min(ay2)); + + if px2 > px1 && py2 > py1 { + s -= (px2 - px1) * (py2 - py1); + } + + s + } +} diff --git a/src/bin/reducing-dishes.rs b/src/bin/reducing-dishes.rs new file mode 100644 index 00000000..c447b7e2 --- /dev/null +++ b/src/bin/reducing-dishes.rs @@ -0,0 +1,47 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn max_satisfaction(mut satisfaction: Vec) -> i32 { + satisfaction.sort_unstable(); + let mut hash = std::collections::HashMap::new(); + Self::f(&satisfaction[..], &mut hash, 0, 1) + } + + fn f( + satisfaction: &[i32], + hash: &mut std::collections::HashMap<(usize, i32), i32>, + start_index: usize, + current_time: i32, + ) -> i32 { + if start_index == satisfaction.len() { + return 0; + } + + let x = if let Some(x) = hash.get(&(start_index + 1, current_time + 1)) { + *x + } else { + let v = Self::f(satisfaction, hash, start_index + 1, current_time + 1); + hash.insert((start_index + 1, current_time + 1), v); + v + }; + + let x = x + satisfaction[start_index] * current_time; + + let y = if let Some(x) = hash.get(&(start_index + 1, current_time)) { + *x + } else { + let v = Self::f(satisfaction, hash, start_index + 1, current_time); + hash.insert((start_index + 1, current_time), v); + v + }; + + let max = x.max(y); + hash.insert((start_index, current_time), max); + + max + } +} diff --git a/src/bin/remove-all-adjacent-duplicates-in-string-ii.rs b/src/bin/remove-all-adjacent-duplicates-in-string-ii.rs new file mode 100644 index 00000000..53501d6a --- /dev/null +++ b/src/bin/remove-all-adjacent-duplicates-in-string-ii.rs @@ -0,0 +1,37 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn remove_duplicates(s: String, k: i32) -> String { + let mut v1 = vec![]; + let mut v2 = vec![]; // 用于计数的栈 + let mut last = 0; + + for i in s.into_bytes().into_iter() { + v1.push(i); + if i != last { + last = i; + v2.push(1); + } else { + let r = v2.pop().unwrap(); + v2.push(r + 1); + if let Some(x) = v2.last() { + if *x == k { + v2.pop(); + v1 = v1[0..v1.len() - k as usize].to_vec(); + if v1.is_empty() { + last = 0; + } else { + last = v1[v1.len() - 1]; + } + } + } + } + } + + String::from_utf8(v1).unwrap() + } +} diff --git a/src/bin/remove-all-adjacent-duplicates-in-string.rs b/src/bin/remove-all-adjacent-duplicates-in-string.rs new file mode 100644 index 00000000..d809d5b7 --- /dev/null +++ b/src/bin/remove-all-adjacent-duplicates-in-string.rs @@ -0,0 +1,24 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn remove_duplicates(s: String) -> String { + let mut v: Vec = vec![]; + + for i in s.chars() { + if let Some(s) = v.last() { + if s == &i { + v.pop(); + continue; + } + } + + v.push(i); + } + + v.iter().collect() + } +} diff --git a/src/bin/remove-comments.rs b/src/bin/remove-comments.rs new file mode 100644 index 00000000..3b6e3e36 --- /dev/null +++ b/src/bin/remove-comments.rs @@ -0,0 +1,60 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn remove_comments(source: Vec) -> Vec { + enum Type { + /// 没有注释 + NoComment, + /// 块注释 + Comment1, + /// 行注释 + Comment2, + } + + let mut s = vec![]; + + let mut new_line = Vec::new(); + let mut t = Type::NoComment; + + for old_line in source { + let mut i = 0; + while i < old_line.len() { + match t { + Type::NoComment => { + if old_line[i..].starts_with("/*") { + t = Type::Comment1; + i += 1; + } else if old_line[i..].starts_with("//") { + t = Type::Comment2; + i += 1; + } else { + new_line.push(old_line.as_bytes()[i]); + } + } + Type::Comment1 => { + if old_line[i..].starts_with("*/") { + i += 1; + t = Type::NoComment; + } + } + Type::Comment2 => { + t = Type::NoComment; + break; + } + } + i += 1; + } + + if !matches!(t, Type::Comment1) && !new_line.is_empty() { + s.push(unsafe { String::from_utf8_unchecked(new_line) }); + new_line = Vec::new(); + } + } + + s + } +} diff --git a/src/bin/remove-duplicate-node-lcci.rs b/src/bin/remove-duplicate-node-lcci.rs new file mode 100644 index 00000000..b79efa66 --- /dev/null +++ b/src/bin/remove-duplicate-node-lcci.rs @@ -0,0 +1,41 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +// Definition for singly-linked list. +#[derive(PartialEq, Eq, Clone, Debug)] +pub struct ListNode { + pub val: i32, + pub next: Option>, +} + +impl ListNode { + #[inline] + fn new(val: i32) -> Self { + ListNode { next: None, val } + } +} + +impl Solution { + pub fn remove_duplicate_nodes(mut head: Option>) -> Option> { + let mut set: std::collections::HashSet = Default::default(); + let mut tmp = Some(Box::new(ListNode { next: None, val: 0 })); + let mut current = &mut tmp.as_mut().unwrap().next; + while head.is_some() { + let mut h = head.unwrap(); + let next = h.next.take(); + let v = h.val; + if !set.contains(&v) { + current.insert(h); + current = &mut current.as_mut().unwrap().next; + set.insert(v); + } + + head = next; + } + + tmp.unwrap().next.take() + } +} diff --git a/src/bin/remove-duplicates-from-sorted-array-ii.rs b/src/bin/remove-duplicates-from-sorted-array-ii.rs new file mode 100644 index 00000000..04d889fb --- /dev/null +++ b/src/bin/remove-duplicates-from-sorted-array-ii.rs @@ -0,0 +1,31 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + let mut v = vec![0, 0, 1, 1, 1, 1, 2, 3, 3]; + let s = Solution::remove_duplicates(&mut v); + println!("{:?}", &v[..s as usize]); +} + +struct Solution; + +impl Solution { + pub fn remove_duplicates(nums: &mut Vec) -> i32 { + let (mut index1, mut num) = (0, 0); + + for i in 0..nums.len() { + if i == 0 || nums[i] == nums[i - 1] { + num += 1; + } else { + num = 1; + } + + if num <= 2 { + nums[index1] = nums[i]; + index1 += 1; + continue; + } + } + + index1 as i32 + } +} diff --git a/src/bin/remove-duplicates-from-sorted-array.rs b/src/bin/remove-duplicates-from-sorted-array.rs new file mode 100644 index 00000000..38d85276 --- /dev/null +++ b/src/bin/remove-duplicates-from-sorted-array.rs @@ -0,0 +1,30 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + assert_eq!( + 5, + Solution::remove_duplicates(&mut vec![0, 0, 1, 1, 1, 2, 2, 3, 3, 4]) + ) +} + +struct Solution; + +impl Solution { + pub fn remove_duplicates(nums: &mut Vec) -> i32 { + if nums.len() == 0 || nums.len() == 1 { + return nums.len() as i32; + } + + let mut slow = 0usize; + + for i in 1..nums.len() { + if nums[i] == nums[slow] { + continue; + } else { + slow += 1; + nums[slow] = nums[i]; + } + } + slow as i32 + 1 + } +} diff --git a/src/bin/remove-duplicates-from-sorted-list-ii.rs b/src/bin/remove-duplicates-from-sorted-list-ii.rs new file mode 100644 index 00000000..154f6542 --- /dev/null +++ b/src/bin/remove-duplicates-from-sorted-list-ii.rs @@ -0,0 +1,52 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +// Definition for singly-linked list. +#[derive(PartialEq, Eq, Clone, Debug)] +pub struct ListNode { + pub val: i32, + pub next: Option>, +} + +impl ListNode { + #[inline] + fn new(val: i32) -> Self { + ListNode { next: None, val } + } +} + +impl Solution { + pub fn delete_duplicates(head: Option>) -> Option> { + let s = Self::func(head); + s.0 + } + + fn func(mut head: Option>) -> (Option>, Option) { + if head.is_none() { + return (None, None); + } + let v = head.as_ref().unwrap().val; + let (node, val) = Self::func(head.as_mut().unwrap().next.take()); + if val.is_none() { + (head, Some(v)) + } else { + if val.unwrap() == v { + if node.is_none() { + (None, Some(v)) + } else { + if node.as_ref().unwrap().val == v { + (node.unwrap().next, Some(v)) + } else { + (node, Some(v)) + } + } + } else { + head.as_mut().unwrap().next = node; + (head, Some(v)) + } + } + } +} diff --git a/src/bin/remove-duplicates-from-sorted-list.rs b/src/bin/remove-duplicates-from-sorted-list.rs new file mode 100644 index 00000000..5e47310f --- /dev/null +++ b/src/bin/remove-duplicates-from-sorted-list.rs @@ -0,0 +1,36 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +// Definition for singly-linked list. +#[derive(PartialEq, Eq, Clone, Debug)] +pub struct ListNode { + pub val: i32, + pub next: Option>, +} + +impl ListNode { + #[inline] + fn new(val: i32) -> Self { + ListNode { next: None, val } + } +} + +impl Solution { + pub fn delete_duplicates(head: Option>) -> Option> { + if head.is_none() { + return None; + } + + let mut head = head; + let node = Self::delete_duplicates(head.as_mut().unwrap().next.take()); + if node.is_some() && head.as_ref().unwrap().val == node.as_ref().unwrap().val { + node + } else { + head.as_mut().unwrap().next = node; + head + } + } +} diff --git a/src/bin/remove-element.rs b/src/bin/remove-element.rs new file mode 100644 index 00000000..f2395c55 --- /dev/null +++ b/src/bin/remove-element.rs @@ -0,0 +1,42 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + let mut v = vec![3, 2, 2, 3]; + assert_eq!(2, Solution::remove_element(&mut v, 3)); + println!("{:?}", v); + + let mut v = vec![0, 1, 2, 2, 3, 0, 4, 2]; + assert_eq!(5, Solution::remove_element(&mut v, 2)); + println!("{:?}", v); + + let mut v = vec![2]; + assert_eq!(1, Solution::remove_element(&mut v, 3)); + println!("{:?}", v); + + let mut v = vec![3, 2, 2, 3]; + assert_eq!(2, Solution::remove_element(&mut v, 3)); + println!("{:?}", v); +} + +struct Solution; + +impl Solution { + pub fn remove_element(nums: &mut Vec, val: i32) -> i32 { + if nums.len() == 0 { + return 0; + } + + let mut j = 0; + + // 快慢指针 + for i in 0..nums.len() { + if nums[i] != val { + let x = nums[j]; + nums[j] = nums[i]; + nums[i] = x; + j += 1; + } + } + j as i32 + } +} diff --git a/src/bin/remove-linked-list-elements.rs b/src/bin/remove-linked-list-elements.rs new file mode 100644 index 00000000..e96ee6ef --- /dev/null +++ b/src/bin/remove-linked-list-elements.rs @@ -0,0 +1,48 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +// Definition for singly-linked list. +#[derive(PartialEq, Eq, Clone, Debug)] +pub struct ListNode { + pub val: i32, + pub next: Option>, +} + +impl ListNode { + #[inline] + fn new(val: i32) -> Self { + ListNode { next: None, val } + } +} + +impl Solution { + pub fn remove_elements(head: Option>, val: i32) -> Option> { + if head.is_none() { + return head; + } + + let mut head = head; + + // 去掉前面都是满足值的节点 + while head.is_some() && head.as_ref().unwrap().val == val { + head = head.as_mut().unwrap().next.take(); + } + + let mut cursor = head.as_mut(); + while cursor.is_some() { + if let Some(i) = cursor.as_mut().unwrap().next.as_mut() { + if i.val == val { + cursor.as_mut().unwrap().next = i.next.take(); + continue; + } + } + + cursor = cursor.unwrap().next.as_mut(); + } + + head + } +} diff --git a/src/bin/remove-nodes-from-linked-list.rs b/src/bin/remove-nodes-from-linked-list.rs new file mode 100644 index 00000000..eb98449c --- /dev/null +++ b/src/bin/remove-nodes-from-linked-list.rs @@ -0,0 +1,46 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +// Definition for singly-linked list. +#[derive(PartialEq, Eq, Clone, Debug)] +pub struct ListNode { + pub val: i32, + pub next: Option>, +} + +impl ListNode { + #[inline] + fn new(val: i32) -> Self { + ListNode { next: None, val } + } +} + +impl Solution { + pub fn remove_nodes(head: Option>) -> Option> { + let mut head = head; + let mut stack = vec![]; + while let Some(mut x) = head.take() { + while let Some(m) = stack.pop() { + if m >= x.val { + stack.push(m); + break; + } + } + stack.push(x.val); + head = x.next.take(); + } + + let mut pre_head = ListNode { val: 0, next: None }; + let mut current = &mut pre_head.next; + + for x in stack { + current.insert(Box::new(ListNode { val: x, next: None })); + current = &mut current.as_mut().unwrap().next; + } + + pre_head.next.take() + } +} diff --git a/src/bin/remove-nth-node-from-end-of-list.rs b/src/bin/remove-nth-node-from-end-of-list.rs new file mode 100644 index 00000000..11e7acc6 --- /dev/null +++ b/src/bin/remove-nth-node-from-end-of-list.rs @@ -0,0 +1,42 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +// Definition for singly-linked list. +#[derive(PartialEq, Eq, Clone, Debug)] +pub struct ListNode { + pub val: i32, + pub next: Option>, +} + +impl ListNode { + #[inline] + fn new(val: i32) -> Self { + ListNode { next: None, val } + } +} + +impl Solution { + pub fn remove_nth_from_end(head: Option>, n: i32) -> Option> { + let (node, _) = Self::func(head, n); + node + } + + fn func(head: Option>, n: i32) -> (Option>, i32) { + if head.is_none() { + return (None, 0); + } + + let mut head = head; + let next = head.as_mut().unwrap().next.take(); + let (node, num) = Self::func(next, n); + if num + 1 == n { + return (node, num + 1); + } + + head.as_mut().unwrap().next = node; + (head, num + 1) + } +} diff --git a/src/bin/remove-stones-to-minimize-the-total.rs b/src/bin/remove-stones-to-minimize-the-total.rs new file mode 100644 index 00000000..f92e24d7 --- /dev/null +++ b/src/bin/remove-stones-to-minimize-the-total.rs @@ -0,0 +1,18 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn min_stone_sum(piles: Vec, k: i32) -> i32 { + let mut heap = std::collections::BinaryHeap::from(piles); + + for _ in 0..k { + let x = heap.pop().unwrap(); + heap.push(if x % 2 == 0 { x / 2 } else { x / 2 + 1 }); + } + + heap.into_iter().sum() + } +} diff --git a/src/bin/remove-trailing-zeros-from-a-string.rs b/src/bin/remove-trailing-zeros-from-a-string.rs new file mode 100644 index 00000000..9c9a0f2a --- /dev/null +++ b/src/bin/remove-trailing-zeros-from-a-string.rs @@ -0,0 +1,21 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn remove_trailing_zeros(num: String) -> String { + let mut num = num; + loop { + match num.as_bytes().last() { + Some(b'0') => { + let _ = num.pop(); + } + _ => break, + } + } + + num + } +} diff --git a/src/bin/remove-zero-sum-consecutive-nodes-from-linked-list.rs b/src/bin/remove-zero-sum-consecutive-nodes-from-linked-list.rs new file mode 100644 index 00000000..8dce1e3b --- /dev/null +++ b/src/bin/remove-zero-sum-consecutive-nodes-from-linked-list.rs @@ -0,0 +1,59 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +// Definition for singly-linked list. +#[derive(PartialEq, Eq, Clone, Debug)] +pub struct ListNode { + pub val: i32, + pub next: Option>, +} + +impl ListNode { + #[inline] + fn new(val: i32) -> Self { + ListNode { next: None, val } + } +} +impl Solution { + pub fn remove_zero_sum_sublists(head: Option>) -> Option> { + if head.is_none() { + return head; + } + + let mut dummy = Box::new(ListNode::new(0)); + dummy.next = head; + + let mut pre_sum = std::collections::HashMap::new(); + pre_sum.insert(0, dummy.as_ref()); + let mut sum = 0; + let mut p = dummy.next.as_ref(); + + while let Some(n) = p { + sum += n.val; + p = n.next.as_ref(); + pre_sum.insert(sum, n.as_ref()); + } + + let mut ans = Box::new(ListNode::new(0)); + let mut p = Some(&mut ans); + let mut sum = 0; + + while let Some(n) = p { + sum += n.val; + + if let Some(q) = pre_sum.get(&sum) { + n.next = match q.next.as_ref() { + Some(next) => Some(Box::new(ListNode::new(next.val))), + None => None, + } + } + + p = n.next.as_mut(); + } + + ans.next + } +} diff --git a/src/bin/removing-minimum-number-of-magic-beans.rs b/src/bin/removing-minimum-number-of-magic-beans.rs new file mode 100644 index 00000000..37e12c90 --- /dev/null +++ b/src/bin/removing-minimum-number-of-magic-beans.rs @@ -0,0 +1,18 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn minimum_removal(beans: Vec) -> i64 { + let mut beans = beans; + beans.sort_unstable(); + let sum: i64 = beans.iter().map(|x| *x as i64).sum(); + let mut r = i64::MAX; + for i in 0..beans.len() { + r = r.min(sum - (beans.len() - i) as i64 * (beans[i] as i64)) + } + r + } +} diff --git a/src/bin/removing-stars-from-a-string.rs b/src/bin/removing-stars-from-a-string.rs new file mode 100644 index 00000000..92ede0e0 --- /dev/null +++ b/src/bin/removing-stars-from-a-string.rs @@ -0,0 +1,20 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn remove_stars(s: String) -> String { + let mut stack = vec![]; + for &i in s.as_bytes() { + if i == b'*' { + stack.pop(); + } else { + stack.push(i); + } + } + + String::from_utf8(stack).unwrap() + } +} diff --git a/src/bin/reorder-list.rs b/src/bin/reorder-list.rs new file mode 100644 index 00000000..6bc18c5b --- /dev/null +++ b/src/bin/reorder-list.rs @@ -0,0 +1,45 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +use std::vec; + +fn main() {} + +struct Solution; + +// Definition for singly-linked list. +#[derive(PartialEq, Eq, Clone, Debug)] +pub struct ListNode { + pub val: i32, + pub next: Option>, +} + +impl ListNode { + #[inline] + fn new(val: i32) -> Self { + ListNode { next: None, val } + } +} +impl Solution { + pub fn reorder_list(mut head: &mut Option>) { + let mut stack = std::collections::VecDeque::new(); + let mut next = head.as_mut().unwrap().next.take(); + while next.is_some() { + let new = next.as_mut().unwrap().next.take(); + stack.push_back(next); + next = new; + } + let mut flag = false; // false标识从栈后面拿 + while !stack.is_empty() { + let next = if flag { + stack.pop_front().unwrap() + } else { + stack.pop_back().unwrap() + }; + + head.as_mut().unwrap().next = next; + head = &mut head.as_mut().unwrap().next; + + flag = !flag; + } + } +} diff --git a/src/bin/reorder-routes-to-make-all-paths-lead-to-the-city-zero.rs b/src/bin/reorder-routes-to-make-all-paths-lead-to-the-city-zero.rs new file mode 100644 index 00000000..22693548 --- /dev/null +++ b/src/bin/reorder-routes-to-make-all-paths-lead-to-the-city-zero.rs @@ -0,0 +1,41 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +#[derive(Clone)] +enum Direction { + Go(i32), + Back(i32), +} + +impl Solution { + pub fn min_reorder(n: i32, connections: Vec>) -> i32 { + let mut c = vec![Vec::new(); n as usize]; + + for i in connections { + c[i[0] as usize].push(Direction::Go(i[1])); + c[i[1] as usize].push(Direction::Back(i[0])); + } + + Self::dfs(0, -1, &c[..]) + } + + fn dfs(x: usize, parent: i32, connections: &[Vec]) -> i32 { + let mut res = 0; + for i in connections[x].iter() { + match *i { + Direction::Back(d) if d != parent => { + res += Self::dfs(d as usize, x as i32, connections); + } + Direction::Go(d) if d != parent => { + res += Self::dfs(d as usize, x as i32, connections) + 1; + } + _ => {} + } + } + + res + } +} diff --git a/src/bin/repeated-dna-sequences.rs b/src/bin/repeated-dna-sequences.rs new file mode 100644 index 00000000..ccfe06b4 --- /dev/null +++ b/src/bin/repeated-dna-sequences.rs @@ -0,0 +1,31 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + println!( + "{:?}", + Solution::find_repeated_dna_sequences("AAAAAAAAAAA".to_string()) + ); +} + +struct Solution; + +impl Solution { + pub fn find_repeated_dna_sequences(s: String) -> Vec { + let mut v = std::collections::HashMap::new(); + let mut r = vec![]; + + for i in 10..=s.len() { + // v.entry(&s[i - 10..i]).and_modify(|x| *x += 1).or_insert(1); + if let Some(x) = v.get_mut(&s[i - 10..i]) { + if *x == 1 { + r.push(s[i - 10..i].to_string()); + } + *x += 1; + } else { + v.insert(&s[i - 10..i], 1); + } + } + + r + } +} diff --git a/src/bin/restore-ip-addresses.rs b/src/bin/restore-ip-addresses.rs new file mode 100644 index 00000000..d3bba93c --- /dev/null +++ b/src/bin/restore-ip-addresses.rs @@ -0,0 +1,62 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + println!( + "{:?}", + Solution::restore_ip_addresses(String::from("25525511135")) + ); + println!("{:?}", Solution::restore_ip_addresses(String::from("0000"))); + println!( + "{:?}", + Solution::restore_ip_addresses(String::from("010010")) + ); + println!("{:?}", Solution::restore_ip_addresses(String::from("1111"))); + println!( + "{:?}", + Solution::restore_ip_addresses(String::from("0279245587303")) + ); +} + +struct Solution; + +impl Solution { + pub fn restore_ip_addresses(s: String) -> Vec { + Self::ip(&s, 4) + } + + fn ip(s: &str, level: i32) -> Vec { + let mut result = vec![]; + + if s.len() < level as usize { + return result; + } + + if level == 1 { + // 这里故意设置为256,使得数字大于255,为true + return if (s.starts_with('0') && s.len() > 1) || s.parse::().unwrap_or(256) > 255 { + result + } else { + vec![String::from(s)] + }; + } + + for i in 0..3 { + if s.len() > i { + if i == 2 && s[..3].parse::().unwrap_or(256) > 255 { + return result; + } + + let r = Self::ip(&s[i + 1..], level - 1); + for j in r { + result.push(format!("{}.{}", &s[0..=i], j)); + } + + if s.starts_with('0') { + return result; + } + } + } + + result + } +} diff --git a/src/bin/reverse-bits.rs b/src/bin/reverse-bits.rs new file mode 100644 index 00000000..715785c8 --- /dev/null +++ b/src/bin/reverse-bits.rs @@ -0,0 +1,24 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + println!("{}", Solution::reverse_bits(43261596)); + println!("{}", Solution::reverse_bits(4294967293)); +} + +struct Solution; + +impl Solution { + pub fn reverse_bits(x: u32) -> u32 { + let mut r = 0u32; + + for a in 0..32u32 { + if a <= 15 { + r |= (x & (1 << a)) << (31 - 2 * a); + } else { + r |= (x & (1 << a)) >> (31 - 2 * (31 - a)); + } + } + + r + } +} diff --git a/src/bin/reverse-integer.rs b/src/bin/reverse-integer.rs new file mode 100644 index 00000000..e77043be --- /dev/null +++ b/src/bin/reverse-integer.rs @@ -0,0 +1,40 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + println!("{}, {}", std::i32::MAX, std::i32::MIN); +} + +struct Solution; + +impl Solution { + pub fn reverse(x: i32) -> i32 { + if x == 0 { + return 0; + } + let mut x = x; + let mut m = 0; + while m == 0 { + m = x % 10; + x /= 10; + } + + while x != 0 { + let s = m.overflowing_mul(10); + if s.1 { + m = 0; + break; + } + + let s = s.0.overflowing_add(x % 10); + if s.1 { + m = 0; + break; + } + + m = s.0; + x /= 10; + } + + m + } +} diff --git a/src/bin/reverse-linked-list.rs b/src/bin/reverse-linked-list.rs new file mode 100644 index 00000000..b68e4f22 --- /dev/null +++ b/src/bin/reverse-linked-list.rs @@ -0,0 +1,46 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +// Definition for singly-linked list. +#[derive(PartialEq, Eq, Clone, Debug)] +pub struct ListNode { + pub val: i32, + pub next: Option>, +} + +impl ListNode { + #[inline] + fn new(val: i32) -> Self { + ListNode { next: None, val } + } +} + +impl Solution { + pub fn reverse_list(head: Option>) -> Option> { + if head.is_none() { + return None; + } + + let mut v = vec![]; + let mut head = head; + + while head.is_some() { + let h = head.as_mut().unwrap().next.take(); + v.push(head); + head = h; + } + + let mut root = v.pop().unwrap(); + let mut s = &mut root; + while !v.is_empty() { + let node = v.pop().unwrap(); + s.as_mut().unwrap().next = node; + s = &mut s.as_mut().unwrap().next; + } + + root + } +} diff --git a/src/bin/reverse-nodes-in-k-group.rs b/src/bin/reverse-nodes-in-k-group.rs new file mode 100644 index 00000000..58e1bff2 --- /dev/null +++ b/src/bin/reverse-nodes-in-k-group.rs @@ -0,0 +1,93 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + let x = Some(Box::new(ListNode { + val: 1, + next: Some(Box::new(ListNode { + val: 2, + next: Some(Box::new(ListNode { + val: 3, + next: Some(Box::new(ListNode { + val: 4, + next: Some(Box::new(ListNode { val: 5, next: None })), + })), + })), + })), + })); + + let r = Solution::reverse_k_group(x, 5); + println!("{:?}", r); +} + +struct Solution; + +// Definition for singly-linked list. +#[derive(PartialEq, Eq, Clone, Debug)] +pub struct ListNode { + pub val: i32, + pub next: Option>, +} + +impl ListNode { + #[inline] + fn new(val: i32) -> Self { + ListNode { next: None, val } + } +} + +impl Solution { + pub fn reverse_k_group(head: Option>, k: i32) -> Option> { + if head.is_none() || k == 1 { + return head; + } + let mut head = head; + let mut k1 = k; + + let mut v = Vec::with_capacity(k as usize); + while k1 > 0 { + k1 -= 1; + let next = head.as_mut().unwrap().next.take(); + v.push(head); + head = next; + if head.is_none() { + break; + } + } + + let x = Self::reverse_k_group(head, k); + if k1 == 0 { + v.first_mut().unwrap().as_mut().unwrap().next = x; + Self::rev_build(&mut v) + } else { + v.last_mut().unwrap().as_mut().unwrap().next = x; + Self::build(&mut v) + } + } + + fn build(v: &mut [Option>]) -> Option> { + if v.len() == 0 { + return None; + } + + let mut root = v[0].take(); + let x = Self::build(&mut v[1..]); + if x.is_some() { + root.as_mut().unwrap().next = x; + } + root + } + + fn rev_build(v: &mut [Option>]) -> Option> { + if v.len() == 0 { + return None; + } + + let mut root = v[v.len() - 1].take(); + let l = v.len() - 1; + let x = Self::rev_build(&mut v[..l]); + if x.is_some() { + root.as_mut().unwrap().next = x; + } + root + } +} diff --git a/src/bin/reverse-odd-levels-of-binary-tree.rs b/src/bin/reverse-odd-levels-of-binary-tree.rs new file mode 100644 index 00000000..44114120 --- /dev/null +++ b/src/bin/reverse-odd-levels-of-binary-tree.rs @@ -0,0 +1,70 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +use std::cell::RefCell; +use std::rc::Rc; + +// Definition for a binary tree node. +#[derive(Debug, PartialEq, Eq)] +pub struct TreeNode { + pub val: i32, + pub left: Option>>, + pub right: Option>>, +} + +impl TreeNode { + #[inline] + pub fn new(val: i32) -> Self { + TreeNode { + val, + left: None, + right: None, + } + } +} + +fn main() {} + +struct Solution; + +impl Solution { + pub fn reverse_odd_levels( + root: Option>>, + ) -> Option>> { + let mut edage = 0; + let mut stack = vec![root.clone()]; + + while !stack.is_empty() { + if edage % 2 == 1 { + let (mut start, mut end) = (0, stack.len() - 1); + while start < end { + let l = stack.get(start).unwrap().as_ref().unwrap().borrow().val; + let r = stack.get(end).unwrap().as_ref().unwrap().borrow().val; + + stack.get(start).unwrap().as_ref().unwrap().borrow_mut().val = r; + stack.get(end).unwrap().as_ref().unwrap().borrow_mut().val = l; + + start += 1; + end -= 1; + } + } + + let mut new_stack = Vec::with_capacity(stack.len() * 2); + while let Some(x) = stack.pop() { + let left = x.as_ref().unwrap().borrow().left.clone(); + if left.is_some() { + new_stack.push(left); + } + let right = x.as_ref().unwrap().borrow().right.clone(); + if right.is_some() { + new_stack.push(right); + } + } + + stack = new_stack; + + edage += 1; + } + + root + } +} diff --git a/src/bin/reverse-only-letters.rs b/src/bin/reverse-only-letters.rs new file mode 100644 index 00000000..5b1580f0 --- /dev/null +++ b/src/bin/reverse-only-letters.rs @@ -0,0 +1,27 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn reverse_only_letters(mut s: String) -> String { + unsafe { + let (mut start, mut end) = (0, s.len() - 1); + let mut bytes = s.as_bytes_mut(); + + while start < end { + if !matches!(bytes[start], b'a'..=b'z'|b'A'..=b'Z') { + start += 1; + } else if !matches!(bytes[end], b'a'..=b'z'|b'A'..=b'Z') { + end -= 1; + } else { + bytes.swap(start, end); + start += 1; + end -= 1; + } + } + } + s + } +} diff --git a/src/bin/reverse-prefix-of-word.rs b/src/bin/reverse-prefix-of-word.rs new file mode 100644 index 00000000..9746fb4d --- /dev/null +++ b/src/bin/reverse-prefix-of-word.rs @@ -0,0 +1,29 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn reverse_prefix(word: String, ch: char) -> String { + let mut word = word; + let mut i = 0; + for (index, value) in word.chars().enumerate() { + if value == ch { + i = index; + } + } + + unsafe { + let mut s = word.as_bytes_mut(); + let mut j = 0; + while j < i { + s.swap(i, j); + i -= 1; + j += 1; + } + } + + word + } +} diff --git a/src/bin/reverse-string-ii.rs b/src/bin/reverse-string-ii.rs new file mode 100644 index 00000000..25ab887b --- /dev/null +++ b/src/bin/reverse-string-ii.rs @@ -0,0 +1,24 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn reverse_str(s: String, k: i32) -> String { + let mut s = s; + let mut start = 0; + unsafe { + let mut d = s.as_bytes_mut(); + while start < d.len() { + let mut b = (start + k as usize - 1).min(d.len() - 1); + let mut a = start; + d[a..=b].reverse(); + + start += 2 * k as usize; + } + } + + s + } +} diff --git a/src/bin/reverse-string.rs b/src/bin/reverse-string.rs new file mode 100644 index 00000000..c7929f7d --- /dev/null +++ b/src/bin/reverse-string.rs @@ -0,0 +1,20 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn reverse_string(s: &mut Vec) { + if s.is_empty() { + return; + } + let (mut s1, mut s2) = (0, s.len() - 1); + + while s1 < s2 { + s.swap(s1, s2); + s1 += 1; + s2 -= 1; + } + } +} diff --git a/src/bin/reverse-vowels-of-a-string.rs b/src/bin/reverse-vowels-of-a-string.rs new file mode 100644 index 00000000..0cefe163 --- /dev/null +++ b/src/bin/reverse-vowels-of-a-string.rs @@ -0,0 +1,39 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn reverse_vowels(s: String) -> String { + let mut s = s; + let mut bytes = unsafe { s.as_bytes_mut() }; + + let (mut start, mut end) = (0, bytes.len() - 1); + + while start < end { + match bytes[start] { + b'A' | b'E' | b'I' | b'O' | b'U' | b'a' | b'e' | b'i' | b'o' | b'u' => {} + _ => { + start += 1; + continue; + } + } + + match bytes[end] { + b'A' | b'E' | b'I' | b'O' | b'U' | b'a' | b'e' | b'i' | b'o' | b'u' => {} + _ => { + end -= 1; + continue; + } + } + + bytes.swap(start, end); + + start += 1; + end -= 1; + } + + s + } +} diff --git a/src/bin/reverse-words-in-a-string.rs b/src/bin/reverse-words-in-a-string.rs new file mode 100644 index 00000000..f22b508f --- /dev/null +++ b/src/bin/reverse-words-in-a-string.rs @@ -0,0 +1,43 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn reverse_words(s: String) -> String { + if s.is_empty() { + return s; + } + let s = s.as_bytes(); + let (mut start, mut end) = (0, s.len() - 1); + + for i in 0..s.len() { + if s[i] != b' ' { + start = i; + break; + } + } + + for i in (0..s.len()).rev() { + if s[i] != b' ' { + end = i; + break; + } + } + + let mut s1 = vec![]; + + for i in (start..end).rev() { + if s[i] == b' ' && s[i + 1] != b' ' { + s1.extend_from_slice(&s[i + 1..=end]); + s1.push(b' '); + } else if s[i] != b' ' && s[i + 1] == b' ' { + end = i; + } + } + + s1.extend_from_slice(&s[start..=end]); + String::from_utf8(Vec::from(s1)).unwrap() + } +} diff --git a/src/bin/reward-top-k-students.rs b/src/bin/reward-top-k-students.rs new file mode 100644 index 00000000..ba98200e --- /dev/null +++ b/src/bin/reward-top-k-students.rs @@ -0,0 +1,47 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn top_students( + positive_feedback: Vec, + negative_feedback: Vec, + report: Vec, + student_id: Vec, + k: i32, + ) -> Vec { + let positive_feedback: std::collections::HashSet<_> = + positive_feedback.iter().map(|x| x.as_str()).collect(); + + let negative_feedback: std::collections::HashSet<_> = + negative_feedback.iter().map(|x| x.as_str()).collect(); + + let mut s = (0..student_id.len()) + .map(|x| { + let mut score = 0; + for i in report[x].split(' ').into_iter() { + if positive_feedback.contains(i) { + score += 3; + } + if negative_feedback.contains(i) { + score -= 1; + } + } + + (score, student_id[x]) + }) + .collect::>(); + + s.sort_unstable_by(|x, y| { + if x.0 != y.0 { + y.0.cmp(&x.0) + } else { + x.1.cmp(&y.1) + } + }); + + s.into_iter().take(k as usize).map(|x| x.1).collect() + } +} diff --git a/src/bin/richest-customer-wealth.rs b/src/bin/richest-customer-wealth.rs new file mode 100644 index 00000000..68b57fbc --- /dev/null +++ b/src/bin/richest-customer-wealth.rs @@ -0,0 +1,11 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn maximum_wealth(accounts: Vec>) -> i32 { + accounts.iter().map(|x| x.iter().sum()).max().unwrap() + } +} diff --git a/src/bin/right-triangles.rs b/src/bin/right-triangles.rs new file mode 100644 index 00000000..56e57ade --- /dev/null +++ b/src/bin/right-triangles.rs @@ -0,0 +1,32 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn number_of_right_triangles(grid: Vec>) -> i64 { + let (mut row, mut col) = (vec![0; grid.len()], vec![0; grid[0].len()]); + + for i in 0..grid.len() { + for j in 0..grid[0].len() { + if grid[i][j] == 1 { + row[i] += 1; + col[j] += 1; + } + } + } + + let mut result = 0; + + for i in 0..grid.len() { + for j in 0..grid[0].len() { + if grid[i][j] == 1 { + result += (row[i] - 1) * (col[j] - 1); + } + } + } + + result + } +} diff --git a/src/bin/rings-and-rods.rs b/src/bin/rings-and-rods.rs new file mode 100644 index 00000000..b371d1d5 --- /dev/null +++ b/src/bin/rings-and-rods.rs @@ -0,0 +1,24 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn count_points(rings: String) -> i32 { + let mut v = vec![0; 10]; + + for i in (0..rings.len()).filter(|x| x % 2 == 1) { + let x: u8 = match rings.as_bytes()[i - 1] { + b'R' => 0b001, + b'G' => 0b010, + b'B' => 0b100, + _ => unreachable!(), + }; + + v[(rings.as_bytes()[i] - b'0') as usize] |= x; + } + + v.into_iter().filter(|x| *x & 0b111u8 == 0b111u8).count() as i32 + } +} diff --git a/src/bin/rle-iterator.rs b/src/bin/rle-iterator.rs new file mode 100644 index 00000000..afebdc63 --- /dev/null +++ b/src/bin/rle-iterator.rs @@ -0,0 +1,56 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + let mut s = RLEIterator::new(vec![3, 8, 0, 9, 2, 5]); + println!("{}", s.next(2)); + println!("{}", s.next(1)); + println!("{}", s.next(1)); + println!("{}", s.next(2)); +} + +struct Solution; + +#[derive(Debug)] +struct RLEIterator { + encoding: Vec, + index: usize, +} + +/** + * `&self` means the method takes an immutable reference. + * If you need a mutable reference, change it to `&mut self` instead. + */ +impl RLEIterator { + fn new(encoding: Vec) -> Self { + Self { encoding, index: 0 } + } + + fn next(&mut self, n: i32) -> i32 { + let mut n = n; + + for i in self.encoding.iter().skip(self.index).step_by(2) { + if *i == 0 { + self.index += 2; + continue; + } + + match n.cmp(i) { + std::cmp::Ordering::Equal => { + let r = self.encoding[self.index + 1]; + self.index += 2; + return r; + } + std::cmp::Ordering::Greater => { + self.index += 2; + n -= *i; + } + std::cmp::Ordering::Less => { + self.encoding[self.index] -= n; + return self.encoding[self.index + 1]; + } + } + } + + -1 + } +} diff --git a/src/bin/robot-bounded-in-circle.rs b/src/bin/robot-bounded-in-circle.rs new file mode 100644 index 00000000..ec6e04bc --- /dev/null +++ b/src/bin/robot-bounded-in-circle.rs @@ -0,0 +1,35 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + assert_eq!(true, Solution::is_robot_bounded(String::from("LLGRL"))); +} + +struct Solution; + +impl Solution { + /// 只有(x,y)不是原点,并且方向和原来的方向一致,最后才回不去 + pub fn is_robot_bounded(instructions: String) -> bool { + let mut start = (0, 0); + let mut direction = 0u8; // 当前的方向,0为向前,1为向左,2为向后,3为向右 + + for &i in instructions.as_bytes().iter() { + if i == b'G' { + if direction == 0 { + start.1 += 1; + } else if direction == 1 { + start.0 -= 1; + } else if direction == 2 { + start.1 -= 1; + } else { + start.0 += 1 + } + } else if i == b'L' { + direction = (direction + 1) % 4; + } else { + direction = (direction - 1) % 4; + } + } + + start == (0, 0) || direction != 0 + } +} diff --git a/src/bin/robot-return-to-origin.rs b/src/bin/robot-return-to-origin.rs new file mode 100644 index 00000000..97dd8c0a --- /dev/null +++ b/src/bin/robot-return-to-origin.rs @@ -0,0 +1,23 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn judge_circle(moves: String) -> bool { + let mut v = (0, 0); + + for i in moves.bytes() { + match i { + b'L' => v.0 -= 1, + b'R' => v.0 += 1, + b'U' => v.1 += 1, + b'D' => v.1 -= 1, + _ => {} + } + } + + v == (0, 0) + } +} diff --git a/src/bin/roman-to-integer.rs b/src/bin/roman-to-integer.rs new file mode 100644 index 00000000..90d83c13 --- /dev/null +++ b/src/bin/roman-to-integer.rs @@ -0,0 +1,72 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + assert_eq!(3, Solution::roman_to_int("III".to_string())); + assert_eq!(4, Solution::roman_to_int("IV".to_string())); + assert_eq!(9, Solution::roman_to_int("IX".to_string())); + assert_eq!(58, Solution::roman_to_int("LVIII".to_string())); + assert_eq!(1994, Solution::roman_to_int("MCMXCIV".to_string())); +} + +struct Solution; + +impl Solution { + pub fn roman_to_int(s: String) -> i32 { + let mut result = 0; + let s = s.as_bytes(); + + for (i, &v) in s.iter().enumerate() { + let m = match v { + b'I' => 1, + b'V' => { + if i != 0 && s[i - 1] == b'I' { + 3 + } else { + 5 + } + } + b'X' => { + if i != 0 && s[i - 1] == b'I' { + 8 + } else { + 10 + } + } + b'L' => { + if i != 0 && s[i - 1] == b'X' { + 30 + } else { + 50 + } + } + b'C' => { + if i != 0 && s[i - 1] == b'X' { + 80 + } else { + 100 + } + } + b'D' => { + if i != 0 && s[i - 1] == b'C' { + 300 + } else { + 500 + } + } + b'M' => { + if i != 0 && s[i - 1] == b'C' { + 800 + } else { + 1000 + } + } + + _ => 0, + }; + + result += m; + } + + result + } +} diff --git a/src/bin/root-equals-sum-of-children.rs b/src/bin/root-equals-sum-of-children.rs new file mode 100644 index 00000000..5f75fb15 --- /dev/null +++ b/src/bin/root-equals-sum-of-children.rs @@ -0,0 +1,36 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +// Definition for a binary tree node. +#[derive(Debug, PartialEq, Eq)] +pub struct TreeNode { + pub val: i32, + pub left: Option>>, + pub right: Option>>, +} + +impl TreeNode { + #[inline] + pub fn new(val: i32) -> Self { + TreeNode { + val, + left: None, + right: None, + } + } +} +use std::cell::RefCell; +use std::rc::Rc; +impl Solution { + pub fn check_tree(root: Option>>) -> bool { + let root = root.unwrap(); + let root_val = root.borrow().val; + let left_val = root.borrow_mut().left.take().unwrap().borrow().val; + let right_val = root.borrow_mut().right.take().unwrap().borrow().val; + + left_val + right_val == root_val + } +} diff --git a/src/bin/rotate-image.rs b/src/bin/rotate-image.rs new file mode 100644 index 00000000..412ae1a8 --- /dev/null +++ b/src/bin/rotate-image.rs @@ -0,0 +1,60 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + let mut v = vec![vec![1, 2, 3], vec![4, 5, 6], vec![7, 8, 9]]; + + Solution::rotate(&mut v); + println!("{:?}", v); + println!("{}", "[[7, 4, 1], [8, 5, 2], [9, 6, 3]]"); +} + +struct Solution; + +impl Solution { + pub fn rotate1(matrix: &mut Vec>) { + let l = matrix.len(); + for i in 0..=l / 2 { + for j in i..l - i - 1 { + let mut next = (i, j); + for k in 0..=3 { + println!("{:?}", next); + + if k == 0 { + next = (i, j); + } else if k == 1 { + next = (j, l - i - 1); + } else if k == 2 { + next = (l - i - 1, l - j - 1); + } else { + next = (l - j - 1, i); + } + + let last = matrix[next.0][next.1]; + matrix[next.0][next.1] = matrix[i][j]; + matrix[i][j] = last; + } + } + } + } + + /// 先沿着右上左下对角线折叠, + /// 然后再沿着中线反转即可实现 + pub fn rotate(matrix: &mut Vec>) { + let l = matrix.len(); + for i in 0..l { + for j in 0..l - i - 1 { + let x = matrix[i][j]; + matrix[i][j] = matrix[l - j - 1][l - i - 1]; + matrix[l - j - 1][l - i - 1] = x; + } + } + + for i in 0..=l / 2 { + for j in 0..l { + let x = matrix[i][j]; + matrix[i][j] = matrix[l - i - 1][j]; + matrix[l - i - 1][j] = x; + } + } + } +} diff --git a/src/bin/rotting-oranges.rs b/src/bin/rotting-oranges.rs new file mode 100644 index 00000000..9c65cd97 --- /dev/null +++ b/src/bin/rotting-oranges.rs @@ -0,0 +1,64 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn oranges_rotting(grid: Vec>) -> i32 { + let mut hash = std::collections::HashSet::new(); + let mut stack = vec![]; + for i in 0..grid.len() { + for j in 0..grid[0].len() { + match grid[i][j] { + 1 => { + hash.insert((i, j)); + } + 2 => stack.push((i, j)), + _ => {} + } + } + } + + let mut result = 0; + while !stack.is_empty() { + let mut new_stack = vec![]; + let len = hash.len(); + while let Some((x, y)) = stack.pop() { + if x > 0 { + if hash.contains(&(x - 1, y)) { + new_stack.push((x - 1, y)); + hash.remove(&(x - 1, y)); + } + } + + if y > 0 { + if hash.contains(&(x, y - 1)) { + new_stack.push((x, y - 1)); + hash.remove(&(x, y - 1)); + } + } + + if hash.contains(&(x + 1, y)) { + new_stack.push((x + 1, y)); + hash.remove(&(x + 1, y)); + } + + if hash.contains(&(x, y + 1)) { + new_stack.push((x, y + 1)); + hash.remove(&(x, y + 1)); + } + } + if hash.len() != len { + result += 1; + } + stack = new_stack; + } + + if hash.is_empty() { + result + } else { + -1 + } + } +} diff --git a/src/bin/running-sum-of-1d-array.rs b/src/bin/running-sum-of-1d-array.rs index d9c3cb87..511306ee 100644 --- a/src/bin/running-sum-of-1d-array.rs +++ b/src/bin/running-sum-of-1d-array.rs @@ -1,3 +1,5 @@ +#![allow(dead_code, unused, unused_variables)] + fn main() {} struct Solution; @@ -16,4 +18,4 @@ impl Solution { sum } -} \ No newline at end of file +} diff --git a/src/bin/same-tree.rs b/src/bin/same-tree.rs new file mode 100644 index 00000000..90544f36 --- /dev/null +++ b/src/bin/same-tree.rs @@ -0,0 +1,59 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +// Definition for a binary tree node. +#[derive(Debug, PartialEq, Eq)] +pub struct TreeNode { + pub val: i32, + pub left: Option>>, + pub right: Option>>, +} + +impl TreeNode { + #[inline] + pub fn new(val: i32) -> Self { + TreeNode { + val, + left: None, + right: None, + } + } +} + +use std::cell::RefCell; +use std::rc::Rc; + +impl Solution { + pub fn is_same_tree( + p: Option>>, + q: Option>>, + ) -> bool { + if (p.is_none() && q.is_some()) || (p.is_some() && q.is_none()) { + return false; + } + + if p.is_none() && q.is_none() { + return true; + } + + let v1 = p.as_ref().unwrap().borrow().val; + let v2 = q.as_ref().unwrap().borrow().val; + if v1 != v2 { + return false; + } + + let p = p.unwrap(); + let q = q.unwrap(); + + let p_left = p.borrow_mut().left.take(); + let p_right = p.borrow_mut().right.take(); + + let q_left = q.borrow_mut().left.take(); + let q_right = q.borrow_mut().right.take(); + + Self::is_same_tree(p_left, q_left) && Self::is_same_tree(p_right, q_right) + } +} diff --git a/src/bin/scramble-string.rs b/src/bin/scramble-string.rs new file mode 100644 index 00000000..a96b5a08 --- /dev/null +++ b/src/bin/scramble-string.rs @@ -0,0 +1,163 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +use std::str::FromStr; + +fn main() { + assert!(!Solution::is_scramble("abcde".into(), "caebd".into())); + assert!(Solution::is_scramble("great".into(), "rgeat".into())); + assert!(Solution::is_scramble("abca".into(), "caba".into())); + assert!(Solution::is_scramble("a".into(), "a".into())); + assert!(!Solution::is_scramble("ab".into(), "xa".into())); + assert!(Solution::is_scramble("aaab".into(), "baaa".into())); + assert!(!Solution::is_scramble( + "ccabcbabcbabbbbcbb".into(), + "bbbbabccccbbbabcba".into() + )); + assert!(Solution::is_scramble( + "abcdbdacbdac".into(), + "bdacabcdbdac".into() + )); +} + +struct Solution; + +impl Solution { + /// 暴力递归 + pub fn force_is_scramble(s1: String, s2: String) -> bool { + if s1.len() <= 1 && s2.len() <= 1 { + return s1 == s2; + } + + let (b1, b2) = (s1.as_str(), s2.as_str()); + for i in 1..s1.len() { + if Solution::force_is_scramble( + String::from_str(&b1[0..i]).unwrap(), + String::from_str(&b2[0..i]).unwrap(), + ) && Solution::force_is_scramble( + String::from_str(&b1[i..b1.len()]).unwrap(), + String::from_str(&b2[i..b2.len()]).unwrap(), + ) { + return true; + } + + if Solution::force_is_scramble( + String::from_str(&b1[i..b1.len()]).unwrap(), + String::from_str(&b2[0..b1.len() - i]).unwrap(), + ) && Solution::force_is_scramble( + String::from_str(&b1[0..i]).unwrap(), + String::from_str(&b2[b2.len() - i..b2.len()]).unwrap(), + ) { + return true; + } + } + + false + } + + /// 递归记忆化搜索 + pub fn recu_is_scramble(s1: String, s2: String) -> bool { + // v[b1的开始索引][b2的开始索引][长度] + let mut v = vec![vec![vec![Option::::None; s1.len() + 1]; s1.len()]; s1.len()]; + + let (b1, b2) = (s1.as_bytes(), s2.as_bytes()); + + Self::check((0, b1.len()), (0, b1.len()), b1, b2, &mut v) + } + + pub fn check( + b1_index: (usize, usize), + b2_index: (usize, usize), + b1: &[u8], + b2: &[u8], + v: &mut Vec>>>, + ) -> bool { + assert_eq!(b1_index.1 - b1_index.0, b2_index.1 - b2_index.0); + + if b1_index.1 - b1_index.0 == 1 { + let r = b1[b1_index.0] == b2[b2_index.0]; + v[b1_index.0][b2_index.0][1] = Some(r); + } + + if let Some(x) = v[b1_index.0][b2_index.0][b1_index.1 - b1_index.0] { + return x; + } + for i in 1..b1_index.1 - b1_index.0 { + if Self::check( + (b1_index.0, b1_index.0 + i), + (b2_index.0, b2_index.0 + i), + b1, + b2, + v, + ) && Self::check( + (b1_index.0 + i, b1_index.1), + (b2_index.0 + i, b2_index.1), + b1, + b2, + v, + ) { + v[b1_index.0][b2_index.0][b1_index.1 - b1_index.0] = Some(true); + return true; + } + + if Self::check( + (b1_index.0, b1_index.0 + i), + (b2_index.1 - i, b2_index.1), + b1, + b2, + v, + ) && Self::check( + (b1_index.0 + i, b1_index.1), + (b2_index.0, b2_index.1 - i), + b1, + b2, + v, + ) { + v[b1_index.0][b2_index.0][b1_index.1 - b1_index.0] = Some(true); + return true; + } + } + + v[b1_index.0][b2_index.0][b1_index.1 - b1_index.0] = Some(false); + false + } + + /// dp + pub fn is_scramble(s1: String, s2: String) -> bool { + let n = s1.len(); + let (b1, b2) = (s1.as_bytes(), s2.as_bytes()); + + let mut v = vec![vec![vec![false; s1.len() + 1]; s1.len()]; s1.len()]; + + for i in 0..n { + for j in 0..n { + v[i][j][1] = b1[i] == b2[j]; + } + } + + for len in 2..=n { + for i in 0..n { + if i + len > n { + break; + } + + for j in 0..n { + if j + len > n { + break; + } + + // 从1个字符开始枚举 + for k in 1..len { + if (v[i][j][k] && v[i + k][j + k][len - k]) + || (v[i][j + len - k][k] && v[i + k][j][len - k]) + { + v[i][j][len] = true; + break; + } + } + } + } + } + + v[0][0][n] + } +} diff --git a/src/bin/search-a-2d-matrix-ii.rs b/src/bin/search-a-2d-matrix-ii.rs new file mode 100644 index 00000000..ee05c291 --- /dev/null +++ b/src/bin/search-a-2d-matrix-ii.rs @@ -0,0 +1,37 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn search_matrix(matrix: Vec>, target: i32) -> bool { + if matrix.is_empty() || matrix[0].is_empty() { + return false; + } + + let (mut i, mut j) = (matrix.len() - 1, 0); + + loop { + match target.cmp(&matrix[i][j]) { + std::cmp::Ordering::Equal => return true, + std::cmp::Ordering::Greater => { + if j == matrix[0].len() - 1 { + return false; + } + + j += 1; + } + std::cmp::Ordering::Less => { + if i == 0 { + return false; + } + + i -= 1; + } + } + } + + false + } +} diff --git a/src/bin/search-a-2d-matrix.rs b/src/bin/search-a-2d-matrix.rs new file mode 100644 index 00000000..16caeef6 --- /dev/null +++ b/src/bin/search-a-2d-matrix.rs @@ -0,0 +1,37 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + // 二叉搜索 + pub fn search_matrix(matrix: Vec>, target: i32) -> bool { + let n = matrix[0].len() - 1; + for i in 0..matrix.len() { + if matrix[i][n] < target { + continue; + } + + if matrix[i][0] > target { + return false; + } + + let (mut start, mut end) = (0, n); + while start <= end { + let mid = (start + end) / 2; + if matrix[i][mid] == target { + return true; + } else if matrix[i][mid] > target { + end = mid - 1; + } else { + start = mid + 1; + } + } + + return false; + } + + false + } +} diff --git a/src/bin/search-in-a-binary-search-tree.rs b/src/bin/search-in-a-binary-search-tree.rs new file mode 100644 index 00000000..0bbb42bc --- /dev/null +++ b/src/bin/search-in-a-binary-search-tree.rs @@ -0,0 +1,46 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +// Definition for a binary tree node. +#[derive(Debug, PartialEq, Eq)] +pub struct TreeNode { + pub val: i32, + pub left: Option>>, + pub right: Option>>, +} + +impl TreeNode { + #[inline] + pub fn new(val: i32) -> Self { + TreeNode { + val, + left: None, + right: None, + } + } +} + +use std::cell::RefCell; +use std::rc::Rc; + +impl Solution { + pub fn search_bst( + root: Option>>, + val: i32, + ) -> Option>> { + let mut root = root; + while let Some(r) = root { + let v = r.borrow().val; + match v.cmp(&val) { + std::cmp::Ordering::Equal => return Some(r), + std::cmp::Ordering::Greater => root = r.borrow_mut().left.take(), + std::cmp::Ordering::Less => root = r.borrow_mut().right.take(), + } + } + + None + } +} diff --git a/src/bin/search-in-rotated-sorted-array-ii.rs b/src/bin/search-in-rotated-sorted-array-ii.rs new file mode 100644 index 00000000..7bc09793 --- /dev/null +++ b/src/bin/search-in-rotated-sorted-array-ii.rs @@ -0,0 +1,61 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + assert_eq!(true, Solution::search(vec![2, 5, 6, 0, 0, 1, 2], 0)); + assert_eq!(false, Solution::search(vec![2, 5, 6, 0, 0, 1, 2], 3)); + assert_eq!( + true, + Solution::search( + vec![1, 1, 1, 1, 1, 1, 1, 1, 1, 13, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + 13 + ) + ); + assert_eq!( + true, + Solution::search( + vec![1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1], + 2 + ) + ); + assert_eq!(true, Solution::search(vec![1, 0, 1, 1, 1], 0)); + assert_eq!(false, Solution::search(vec![1], 0)); + assert_eq!(true, Solution::search(vec![1], 1)); +} + +struct Solution; + +impl Solution { + pub fn search(nums: Vec, target: i32) -> bool { + let (mut start, mut end) = (0, nums.len() - 1); + + while start <= end { + let mid = (start + end) / 2; + if nums[mid] == target { + return true; + } + + if start == 0 && end == 0 { + return false; + } + + if nums[start] == nums[mid] && nums[mid] == nums[end] { + start += 1; + end -= 1; + } else if nums[start] <= nums[mid] { + if nums[start] <= target && nums[mid] > target { + end = mid - 1; + } else { + start = mid + 1; + } + } else { + if nums[mid] < target && target <= nums[nums.len() - 1] { + start = mid + 1; + } else { + end = mid - 1; + } + } + } + + false + } +} diff --git a/src/bin/search-in-rotated-sorted-array.rs b/src/bin/search-in-rotated-sorted-array.rs new file mode 100644 index 00000000..de87cf0b --- /dev/null +++ b/src/bin/search-in-rotated-sorted-array.rs @@ -0,0 +1,52 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + assert_eq!(4, Solution::search(vec![4, 5, 6, 7, 8, 1, 2, 3], 8)); + assert_eq!(-1, Solution::search(vec![1, 3], 0)); + assert_eq!(-1, Solution::search(vec![1], 0)); + assert_eq!(4, Solution::search(vec![4, 5, 6, 7, 0, 1, 2], 0)); + assert_eq!(-1, Solution::search(vec![4, 5, 6, 7, 0, 1, 2], 3)); + assert_eq!(0, Solution::search(vec![5, 1, 3], 5)); + println!("xxxxx"); + assert_eq!(2, Solution::search(vec![5, 1, 3], 3)); +} + +struct Solution; + +impl Solution { + /// 先判断终点落在上半区还行下半区 + /// 在判断target在上半区还是下半区 + /// 要先判断中点落在哪个分区里面 + pub fn search(nums: Vec, target: i32) -> i32 { + let (mut start, mut end) = (0, nums.len() - 1); + let mut middle = (start + end) >> 1; + + while start < end { + if nums[middle] == target { + break; + } else if nums[middle] > target { + // 如果middle在前半区且target大于等于第一个元素,或者middle在后半区 + if (nums[start] < nums[middle] && target >= nums[start]) + || nums[start] > nums[middle] + { + end = middle; + } else { + start = middle + 1; + } + } else { + if (nums[end] > nums[middle] && nums[end] >= target) || nums[end] < nums[middle] { + start = middle + 1; + } else { + end = middle; + } + } + middle = (start + end) >> 1; + } + + if nums[middle] == target { + middle as i32 + } else { + -1 + } + } +} diff --git a/src/bin/search-insert-position.rs b/src/bin/search-insert-position.rs new file mode 100644 index 00000000..1c97a2b0 --- /dev/null +++ b/src/bin/search-insert-position.rs @@ -0,0 +1,42 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + // assert_eq!(2, Solution::search_insert(vec![1, 3, 5, 6], 5)); + // assert_eq!(1, Solution::search_insert(vec![1, 3, 5, 6], 2)); + // assert_eq!(4, Solution::search_insert(vec![1, 3, 5, 6], 7)); + // assert_eq!(0, Solution::search_insert(vec![1, 3, 5, 6], 0)); + // assert_eq!(2, Solution::search_insert(vec![1, 2, 4, 6, 7], 3)); + // assert_eq!(0, Solution::search_insert(vec![1, 3, 5], 1)); + // assert_eq!(0, Solution::search_insert(vec![1, 3], 0)); + assert_eq!(1, Solution::search_insert(vec![1, 3], 2)); +} + +struct Solution; + +impl Solution { + pub fn search_insert(nums: Vec, target: i32) -> i32 { + let (mut start, mut end) = (0, nums.len() - 1); + while start < end { + let middle = (start + end) >> 1; + if nums[middle] == target { + break; + } else if nums[middle] < target { + start = middle + 1; + } else { + end = if middle > 1 { middle - 1 } else { 0 }; + } + } + let middle = (start + end) >> 1; + if nums[middle] > target { + if middle > 0 { + middle as i32 + } else { + 0 + } + } else if nums[middle] < target { + middle as i32 + 1 + } else { + middle as i32 + } + } +} diff --git a/src/bin/sender-with-largest-word-count.rs b/src/bin/sender-with-largest-word-count.rs new file mode 100644 index 00000000..ced5d40e --- /dev/null +++ b/src/bin/sender-with-largest-word-count.rs @@ -0,0 +1,30 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn largest_word_count(messages: Vec, senders: Vec) -> String { + let mut h = std::collections::HashMap::new(); + + for (i, v) in messages.iter().enumerate() { + let n = v.split(' ').count(); + h.entry(&senders[i]) + .and_modify(|x| *x += n as i32) + .or_insert(n as i32); + } + let mut r = &String::new(); + let mut i = 0; + for (n, v) in h { + if v > i { + r = n; + i = v; + } else if v == i { + r = r.max(n); + } + } + + r.clone() + } +} diff --git a/src/bin/separate-black-and-white-balls.rs b/src/bin/separate-black-and-white-balls.rs new file mode 100644 index 00000000..8e91d7c9 --- /dev/null +++ b/src/bin/separate-black-and-white-balls.rs @@ -0,0 +1,21 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn minimum_steps(s: String) -> i64 { + let mut index = 0; + let mut result = 0; + let s = s.as_bytes(); + for i in 0..s.len() { + if s[i] == b'0' { + result += (i - index) as i64; + index += 1; + } + } + + result + } +} diff --git a/src/bin/serialize-and-deserialize-binary-tree.rs b/src/bin/serialize-and-deserialize-binary-tree.rs new file mode 100644 index 00000000..7d4757b3 --- /dev/null +++ b/src/bin/serialize-and-deserialize-binary-tree.rs @@ -0,0 +1,121 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() { + let mut c = Codec::new(); + println!("{:?}", c.deserialize(r#"{"val": 1, "left": {"val": 2, "left": null, "right": null}, "right": {"val": 3, "left": {"val": 4, "left": null, "right": null}, "right": {"val": 5, "left": null, "right": null}}}"#.into())); + println!("{:?}", c.deserialize(r#"{"val": 4, "left": {"val": -7, "left": null, "right": null}, "right": {"val": -3, "left": {"val": -9, "left": {"val": 9, "left": {"val": 6, "left": {"val": 0, "left": null, "right": {"val": -1, "left": null, "right": null}}, "right": {"val": 6, "left": {"val": -4, "left": null, "right": null}, "right": null}}, "right": null}, "right": {"val": -7, "left": {"val": -6, "left": {"val": 5, "left": null, "right": null}, "right": null}, "right": {"val": -6, "left": {"val": 9, "left": {"val": -2, "left": null, "right": null}, "right": null}, "right": null}}}, "right": {"val": -3, "left": {"val": -4, "left": null, "right": null}, "right": null}}}"#.into())); +} + +struct Solution; + +// Definition for a binary tree node. +#[derive(Debug, PartialEq, Eq)] +pub struct TreeNode { + pub val: i32, + pub left: Option>>, + pub right: Option>>, +} + +impl TreeNode { + #[inline] + pub fn new(val: i32) -> Self { + TreeNode { + val, + left: None, + right: None, + } + } +} + +use std::cell::RefCell; +use std::rc::Rc; +struct Codec { + buffer: String, +} + +/** + * `&self` means the method takes an immutable reference. + * If you need a mutable reference, change it to `&mut self` instead. + */ +impl Codec { + fn new() -> Self { + Self { + buffer: String::new(), + } + } + + fn serialize(&mut self, root: Option>>) -> String { + self.s(root); + self.buffer.to_owned() + } + + fn s(&mut self, root: Option>>) { + match root { + None => { + self.buffer.push_str("null"); + } + Some(r) => { + self.buffer.push_str("{"); + self.buffer.push_str(r#""val": "#); + self.buffer.push_str(&format!("{}, ", r.borrow().val)); + self.buffer.push_str(r#""left": "#); + self.s(r.borrow_mut().left.take()); + self.buffer.push_str(", "); + self.buffer.push_str(r#""right": "#); + self.s(r.borrow_mut().right.take()); + self.buffer.push_str("}"); + } + } + } + + fn deserialize(&self, data: String) -> Option>> { + self.d(&mut data.as_bytes()) + } + + fn d(&self, data: &mut &[u8]) -> Option>> { + let mut node = None; + if data.starts_with(&[b'n', b'u', b'l', b'l']) { + *data = &data[4..]; + return node; + } + + loop { + if data.starts_with(&[b'{']) { + *data = &data[1..]; + } else if data.starts_with(&[b'"', b'l', b'e', b'f', b't', b'"', b':', b' ']) { + *data = &data[8..]; + node.get_or_insert(Rc::new(RefCell::new(TreeNode::new(-1)))) + .borrow_mut() + .left = self.d(data); + } else if data.starts_with(&[b'"', b'r', b'i', b'g', b'h', b't', b'"', b':', b' ']) { + *data = &data[9..]; + node.get_or_insert(Rc::new(RefCell::new(TreeNode::new(-1)))) + .borrow_mut() + .right = self.d(data); + } else if data.starts_with(&[b'"', b'v', b'a', b'l', b'"', b':', b' ']) { + *data = &data[7..]; + let mut v = 0; + let mut sign = 1; + let mut i = 0usize; + if data.starts_with(&[b'-']) { + *data = &data[1..]; + sign = -1; + } + + while data[i] >= b'0' && data[i] <= b'9' { + v = v * 10 + (data[i] - b'0') as i32; + *data = &data[1..]; + } + + node.get_or_insert(Rc::new(RefCell::new(TreeNode::new(-1)))) + .borrow_mut() + .val = v * sign; + } else if data.starts_with(&[b'}']) { + *data = &data[1..]; + return node; + } else { + *data = &data[1..]; + } + } + } +} diff --git a/src/bin/serialize-and-deserialize-bst.rs b/src/bin/serialize-and-deserialize-bst.rs new file mode 100644 index 00000000..bc636a6d --- /dev/null +++ b/src/bin/serialize-and-deserialize-bst.rs @@ -0,0 +1,95 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +// Definition for a binary tree node. +#[derive(Debug, PartialEq, Eq)] +pub struct TreeNode { + pub val: i32, + pub left: Option>>, + pub right: Option>>, +} + +impl TreeNode { + #[inline] + pub fn new(val: i32) -> Self { + TreeNode { + val, + left: None, + right: None, + } + } +} + +use std::cell::RefCell; +use std::rc::Rc; + +/** + * Your Codec object will be instantiated and called as such: + * let obj = Codec::new(); + * let data: String = obj.serialize(strs); + * let ans: Option>> = obj.deserialize(data); + */ +struct Codec {} + +/** + * `&self` means the method takes an immutable reference. + * If you need a mutable reference, change it to `&mut self` instead. + */ +impl Codec { + fn new() -> Self { + Self {} + } + + /// 当为None是序列化为-1 + fn serialize(&self, root: Option>>) -> String { + match root { + Some(root) => { + let value = root.borrow().val; + let left = root.borrow_mut().left.take(); + let right = root.borrow_mut().right.take(); + format!( + "{},{},{}", + self.serialize(left), + value, + self.serialize(right), + ) + } + None => "-1".to_string(), + } + } + + fn deserialize(&self, data: String) -> Option>> { + println!("{:?}", data); + let s = data + .split(',') + .into_iter() + .map(|x| x.parse().unwrap()) + .collect::>(); + + self.f(&s[..], &mut 0) + } + + fn f(&self, data: &[i32], index: &mut usize) -> Option>> { + if data.len() <= *index || data[*index] == -1 { + return None; + } + + let mut node = TreeNode::new(data[*index]); + *index += 1; + if data[*index] != -1 { + node.left = self.f(data, index); + } else { + node.left = None; + } + + *index += 1; + if data[*index] != -1 { + node.right = self.f(data, index); + } else { + node.right = None; + } + + Some(Rc::new(RefCell::new(node))) + } +} diff --git a/src/bin/set-matrix-zeroes.rs b/src/bin/set-matrix-zeroes.rs new file mode 100644 index 00000000..d80698e3 --- /dev/null +++ b/src/bin/set-matrix-zeroes.rs @@ -0,0 +1,82 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + let mut x = vec![vec![1, 1, 1], vec![1, 0, 1], vec![1, 1, 1]]; + Solution::set_zeroes(&mut x); +} + +struct Solution; + +impl Solution { + /// 扫描。常规做法 + pub fn set_zeroes1(matrix: &mut Vec>) { + let (mut v1, mut v2) = (vec![0; matrix.len()], vec![0; matrix[0].len()]); + for i in 0..matrix.len() { + for j in 0..matrix[0].len() { + if matrix[i][j] == 0 { + v1[i] = 1; + v2[j] = 1; + } + } + } + + for i in 0..matrix.len() { + for j in 0..matrix[0].len() { + if v1[i] == 1 || v2[j] == 1 { + matrix[i][j] = 0; + } + } + } + } + + /// 常规空间的做法 + /// 标记做法:循环遍历每个元素,当元素为0时将这个元素对应的第一行的元素和第一列的元素都改为0 + /// 然后从(1,1)开始遍历 + /// 如果第一行或者第一列存在0,还要改变第一行和第一列 + pub fn set_zeroes(matrix: &mut Vec>) { + let (mut row, mut column) = (false, false); + + for i in 0..matrix.len() { + if matrix[i][0] == 0 { + column = true; + break; + } + } + + for j in 0..matrix[0].len() { + if matrix[0][j] == 0 { + row = true; + break; + } + } + + for i in 0..matrix.len() { + for j in 0..matrix[0].len() { + if matrix[i][j] == 0 { + matrix[i][0] = 0; + matrix[0][j] = 0; + } + } + } + + for i in 1..matrix.len() { + for j in 1..matrix[0].len() { + if matrix[i][0] == 0 || matrix[0][j] == 0 { + matrix[i][j] = 0; + } + } + } + + if row { + for j in 0..matrix[0].len() { + matrix[0][j] = 0; + } + } + + if column { + for i in 0..matrix.len() { + matrix[i][0] = 0; + } + } + } +} diff --git a/src/bin/sfvd7V.rs b/src/bin/sfvd7V.rs new file mode 100644 index 00000000..29c3f408 --- /dev/null +++ b/src/bin/sfvd7V.rs @@ -0,0 +1,29 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn group_anagrams(strs: Vec) -> Vec> { + let mut map = std::collections::HashMap::<[u8; 26], Vec>::new(); + + for s in strs { + let mut v = [0u8; 26]; + for &j in s.as_bytes() { + v[(j - b'a') as usize] += 1; + } + + match map.entry(v) { + std::collections::hash_map::Entry::Occupied(mut entry) => { + entry.get_mut().push(s); + } + std::collections::hash_map::Entry::Vacant(entry) => { + entry.insert(vec![s]); + } + } + } + + map.into_iter().map(|(x, y)| y).collect() + } +} diff --git a/src/bin/shan-chu-lian-biao-de-jie-dian-lcof.rs b/src/bin/shan-chu-lian-biao-de-jie-dian-lcof.rs new file mode 100644 index 00000000..1256307d --- /dev/null +++ b/src/bin/shan-chu-lian-biao-de-jie-dian-lcof.rs @@ -0,0 +1,41 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +// Definition for singly-linked list. +#[derive(PartialEq, Eq, Clone, Debug)] +pub struct ListNode { + pub val: i32, + pub next: Option>, +} + +impl ListNode { + #[inline] + fn new(val: i32) -> Self { + ListNode { next: None, val } + } +} + +impl Solution { + pub fn delete_node(head: Option>, val: i32) -> Option> { + let mut result: Option> = None; + let (mut node, mut last_node) = (head, result.as_mut()); + while node.is_some() { + let mut n = node.unwrap(); + if n.val != val { + if let Some(i) = last_node { + (*i).next = Some(Box::new(ListNode::new(n.val))); + last_node = i.next.as_mut(); + } else { + result = Some(Box::new(ListNode::new(n.val))); + last_node = result.as_mut(); + } + } + node = n.next.take(); + } + + result + } +} diff --git a/src/bin/short-encoding-of-words.rs b/src/bin/short-encoding-of-words.rs new file mode 100644 index 00000000..15af2392 --- /dev/null +++ b/src/bin/short-encoding-of-words.rs @@ -0,0 +1,93 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +use std::fmt::Debug; + +fn main() { + assert_eq!( + Solution::minimum_length_encoding(vec![ + "time".to_string(), + "me".to_string(), + "bell".to_string(), + ],), + 10 + ); + + assert_eq!(Solution::minimum_length_encoding(vec!["t".to_string()]), 2); + assert_eq!( + Solution::minimum_length_encoding(vec![ + "time".to_string(), + "atime".to_string(), + "btime".to_string(), + ]), + 12 + ); + assert_eq!( + Solution::minimum_length_encoding(vec!["me".to_string(), "time".to_string()]), + 5 + ); +} + +struct Solution; + +impl Solution { + pub fn minimum_length_encoding(words: Vec) -> i32 { + let mut words = words; + words.sort_unstable_by(|x, y| x.len().cmp(&y.len()).reverse()); + let mut set = std::collections::HashSet::::new(); + + 'L: for i in words { + for j in set.iter() { + if j.ends_with(i.as_str()) { + continue 'L; + } + } + + set.insert(i); + } + + set.iter().map(|x| x.len() as i32).sum::() + set.len() as i32 + } + + // tire tree 字典树 + // pub fn minimum_length_encoding(words: Vec) -> i32 { + // struct TireTree { + // nodes: std::collections::HashMap, + // } + // + // impl TireTree { + // fn new() -> Self { + // TireTree { + // nodes: std::collections::HashMap::new(), + // } + // } + // + // // 如果为true则表示插入了新的 + // fn insert(&mut self, word: &str) -> bool { + // if word.is_empty() { + // return false; + // } + // + // let k = word.as_bytes()[word.len() - 1]; + // + // if let Some(n) = self.nodes.get_mut(&k) { + // n.insert(&word[..word.len() - 1]) + // } else { + // let mut n = TireTree::new(); + // let x = n.insert(&word[..word.len() - 1]); + // self.nodes.insert(k, n); + // true + // } + // } + // } + // + // let mut tree = TireTree::new(); + // let mut result = 0; + // for i in words.iter() { + // if tree.insert(i.as_str()) { + // result += i.len() as i32 + 1; + // } + // } + // + // result + // } +} diff --git a/src/bin/shortest-unsorted-continuous-subarray.rs b/src/bin/shortest-unsorted-continuous-subarray.rs new file mode 100644 index 00000000..36f2ac0b --- /dev/null +++ b/src/bin/shortest-unsorted-continuous-subarray.rs @@ -0,0 +1,64 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + /// 普通法 + /// 排序,挨个比较 + pub fn find_unsorted_subarray1(nums: Vec) -> i32 { + let mut n = nums.clone(); + n.sort(); + let (mut start, mut end) = (-1, -1); + + for i in 0..nums.len() { + if nums[i] != n[i] { + if start == -1 { + start = i as i32; + } else { + end = i as i32; + } + } + } + + if start == -1 { + 0 + } else { + end - start + 1 + } + } + + // pub fn find_unsorted_subarray(nums: Vec) -> i32 { + // let mut start = 0; + // let mut end = nums.len() - 1; + + // for i in 1..nums.len() { + // if nums[i] > nums[i - 1] { + // start = i; + // } else { + // break; + // } + // } + + // for i in (0..nums.len() - 1).rev() { + // if nums[i] < nums[i + 1] { + // end = i; + // } else { + // break; + // } + // } + + // for i in start..end { + // while nums[i] < nums[start] { + // start -= 1; + // } + + // while nums[i] > nums[end] { + // end += 1; + // } + // } + + // (end - start + 1) as i32 + // } +} diff --git a/src/bin/shu-de-zi-jie-gou-lcof.rs b/src/bin/shu-de-zi-jie-gou-lcof.rs new file mode 100644 index 00000000..75441da5 --- /dev/null +++ b/src/bin/shu-de-zi-jie-gou-lcof.rs @@ -0,0 +1,67 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +// Definition for a binary tree node. +#[derive(Debug, PartialEq, Eq)] +pub struct TreeNode { + pub val: i32, + pub left: Option>>, + pub right: Option>>, +} + +impl TreeNode { + #[inline] + pub fn new(val: i32) -> Self { + TreeNode { + val, + left: None, + right: None, + } + } +} +use std::cell::RefCell; +use std::rc::Rc; + +impl Solution { + pub fn is_sub_structure( + a: Option>>, + b: Option>>, + ) -> bool { + if !(b.is_some() && a.is_some()) { + return false; + } + + if Self::recurse(a.clone(), b.clone()) { + return true; + } + + Self::is_sub_structure(a.as_ref().unwrap().borrow().left.clone(), b.clone()) + || Self::is_sub_structure(a.as_ref().unwrap().borrow().right.clone(), b.clone()) + } + + fn recurse(a: Option>>, b: Option>>) -> bool { + if b.is_none() { + return true; + } + + if a.is_none() { + return false; + } + + let a_value = a.as_ref().unwrap().borrow().val; + let b_value = b.as_ref().unwrap().borrow().val; + + if a_value != b_value { + return false; + } + + let mut b_left = b.as_ref().unwrap().borrow().left.clone(); + let mut b_right = b.as_ref().unwrap().borrow().right.clone(); + + Self::recurse(a.as_ref().unwrap().borrow().left.clone(), b_left) + && Self::recurse(a.as_ref().unwrap().borrow().right.clone(), b_right) + } +} diff --git a/src/bin/shu-ju-liu-zhong-de-zhong-wei-shu-lcof.rs b/src/bin/shu-ju-liu-zhong-de-zhong-wei-shu-lcof.rs new file mode 100644 index 00000000..adc6d1f3 --- /dev/null +++ b/src/bin/shu-ju-liu-zhong-de-zhong-wei-shu-lcof.rs @@ -0,0 +1,231 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +use std::vec; + +fn main() { + let mut finder = MedianFinder::new(); + finder.add_num(1); + finder.add_num(2); + + println!("{}", finder.find_median()); + + finder.add_num(3); + + println!("{}", finder.find_median()); +} + +enum Type { + Big, + Small, +} + +struct Heap { + data: Vec, + r#type: Type, +} + +impl Heap { + fn get_top(&self) -> i32 { + self.data[0] + } + + fn insert(&mut self, value: i32) { + self.data.push(value); + self.heapify(); + } + + fn heapify(&mut self) { + let mut index = self.len() - 1; + while index != 0 { + match self.r#type { + Type::Big if self.data[index] > self.data[(index - 1) / 2] => { + self.data.swap(index, (index - 1) / 2); + } + Type::Small if self.data[index] < self.data[(index - 1) / 2] => { + self.data.swap(index, (index - 1) / 2); + } + _ => { + return; + } + } + + index = (index - 1) / 2; + } + } + + fn down_heap(&mut self) { + let mut index = 0; + while index < self.len() { + match self.r#type { + Type::Big => { + let son_index = if index * 2 + 2 < self.len() { + if self.data[index * 2 + 2] > self.data[index * 2 + 1] { + index * 2 + 2 + } else { + index * 2 + 1 + } + } else if index * 2 + 1 < self.len() { + index * 2 + 1 + } else { + return; + }; + + if self.data[son_index] > self.data[index] { + self.data.swap(son_index, index); + index = son_index; + } else { + return; + } + } + Type::Small => { + let son_index = if index * 2 + 2 < self.len() { + if self.data[index * 2 + 2] < self.data[index * 2 + 1] { + index * 2 + 2 + } else { + index * 2 + 1 + } + } else if index * 2 + 1 < self.len() { + index * 2 + 1 + } else { + return; + }; + + if self.data[son_index] < self.data[index] { + self.data.swap(son_index, index); + index = son_index; + } else { + return; + } + } + } + } + } + + fn pop(&mut self) -> i32 { + let last = self.len() - 1; + self.data.swap(0, last); + let pop = self.data.remove(last); + self.down_heap(); + pop + } + + fn len(&self) -> usize { + self.data.len() + } +} + +struct MedianFinder { + low: Heap, // 大顶推存值小的一半 + high: Heap, // 小顶堆村值大的一半 +} + +/** + * `&self` means the method takes an immutable reference. + * If you need a mutable reference, change it to `&mut self` instead. + */ +impl MedianFinder { + /** initialize your data structure here. */ + fn new() -> Self { + Self { + low: Heap { + data: vec![], + r#type: Type::Big, + }, + high: Heap { + data: vec![], + r#type: Type::Small, + }, + } + } + + fn add_num(&mut self, num: i32) { + // 先把数据插入到 high,再从 high 中弹出一个元素插入到 low + if self.low.len() == self.high.len() { + self.low.insert(num); + let pop = self.low.pop(); + self.high.insert(pop); + } else { + self.high.insert(num); + let pop = self.high.pop(); + self.low.insert(pop); + } + } + + fn find_median(&self) -> f64 { + assert!(self.high.len() + self.low.len() > 0, "empty"); + + if self.high.len() != self.low.len() { + self.high.get_top() as f64 + } else { + (self.high.get_top() as f64 + self.low.get_top() as f64) / 2f64 + } + } +} + +// /** +// * Your MedianFinder object will be instantiated and called as such: +// * let obj = MedianFinder::new(); +// * obj.add_num(num); +// * let ret_2: f64 = obj.find_median(); +// */ +#[test] +fn test_min_heap() { + let mut min_heap = Heap { + data: vec![], + r#type: Type::Small, + }; + + min_heap.insert(10); + min_heap.insert(1); + min_heap.insert(3); + min_heap.insert(9); + min_heap.insert(8); + min_heap.insert(2); + min_heap.insert(7); + + assert_eq!(min_heap.pop(), 1); + assert_eq!(min_heap.pop(), 2); + assert_eq!(min_heap.pop(), 3); + assert_eq!(min_heap.pop(), 7); + assert_eq!(min_heap.pop(), 8); + assert_eq!(min_heap.pop(), 9); + assert_eq!(min_heap.pop(), 10); +} + +#[test] +fn test_max_heap() { + let mut max_heap = Heap { + data: vec![], + r#type: Type::Big, + }; + + max_heap.insert(10); + println!("{:?}", max_heap.data); + max_heap.insert(1); + println!("{:?}", max_heap.data); + max_heap.insert(3); + println!("{:?}", max_heap.data); + max_heap.insert(9); + println!("{:?}", max_heap.data); + max_heap.insert(8); + println!("{:?}", max_heap.data); + max_heap.insert(2); + println!("{:?}", max_heap.data); + max_heap.insert(7); + println!("{:?}", max_heap.data); + + assert_eq!(max_heap.pop(), 10); + println!("{:?}", max_heap.data); + assert_eq!(max_heap.pop(), 9); + println!("{:?}", max_heap.data); + assert_eq!(max_heap.pop(), 8); + println!("{:?}", max_heap.data); + assert_eq!(max_heap.pop(), 7); + println!("{:?}", max_heap.data); + assert_eq!(max_heap.pop(), 3); + println!("{:?}", max_heap.data); + assert_eq!(max_heap.pop(), 2); + println!("{:?}", max_heap.data); + assert_eq!(max_heap.pop(), 1); + println!("{:?}", max_heap.data); +} diff --git a/src/bin/shu-zhi-de-zheng-shu-ci-fang-lcof.rs b/src/bin/shu-zhi-de-zheng-shu-ci-fang-lcof.rs new file mode 100644 index 00000000..72e2f88b --- /dev/null +++ b/src/bin/shu-zhi-de-zheng-shu-ci-fang-lcof.rs @@ -0,0 +1,30 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() { + println!("{}", Solution::my_pow(2.00000, 10)); + println!("{}", Solution::my_pow(2.10000, 3)); + println!("{}", Solution::my_pow(2.00000, -2)); +} + +struct Solution; + +impl Solution { + pub fn my_pow(x: f64, n: i32) -> f64 { + Self::pow(x, n as i64) + } + + fn pow(x: f64, n: i64) -> f64 { + if n == 0 { + return 1.0; + } + + let m = Self::pow(x, n.abs() / 2); + let mut r = if n.abs() % 2 == 1 { m * m * x } else { m * m }; + + if n < 0 { + r = 1f64 / r; + } + + r + } +} diff --git a/src/bin/shu-zi-xu-lie-zhong-mou-yi-wei-de-shu-zi-lcof.rs b/src/bin/shu-zi-xu-lie-zhong-mou-yi-wei-de-shu-zi-lcof.rs new file mode 100644 index 00000000..a513eafc --- /dev/null +++ b/src/bin/shu-zi-xu-lie-zhong-mou-yi-wei-de-shu-zi-lcof.rs @@ -0,0 +1,41 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() { + // println!("{}", Solution::find_nth_digit(3)); + println!("{}", Solution::find_nth_digit(11)); + println!("{}", Solution::find_nth_digit(20)); + println!("{}", Solution::find_nth_digit(21)); + println!("{}", Solution::find_nth_digit(3322432)); + println!("{}", Solution::find_nth_digit(324365434)); + println!("{}", Solution::find_nth_digit(95493394)); + println!("{}", Solution::find_nth_digit(1000000000)); +} + +struct Solution; + +impl Solution { + pub fn find_nth_digit(mut n: i32) -> i32 { + if n <= 9 { + return n; + } + + let mut n = n - 10; + let mut i = 2; + + // 2^31为10位的数字 + while i < 9 { + let s = (i as i32) * 9 * 10i32.pow(i - 1); + if n >= s { + n -= s; + } else { + break; + } + i += 1; + } + + let num = n / i as i32 + 10i32.pow(i - 1); + let digit = n % i as i32; + + num / (10i32.pow(i - digit as u32 - 1)) % 10 + } +} diff --git a/src/bin/shu-zu-zhong-chu-xian-ci-shu-chao-guo-yi-ban-de-shu-zi-lcof.rs b/src/bin/shu-zu-zhong-chu-xian-ci-shu-chao-guo-yi-ban-de-shu-zi-lcof.rs new file mode 100644 index 00000000..90daeddc --- /dev/null +++ b/src/bin/shu-zu-zhong-chu-xian-ci-shu-chao-guo-yi-ban-de-shu-zi-lcof.rs @@ -0,0 +1,36 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn majority_element1(mut nums: Vec) -> i32 { + nums.sort(); + + nums[nums.len() / 2] + } + + /// https://leetcode.cn/problems/shu-zu-zhong-chu-xian-ci-shu-chao-guo-yi-ban-de-shu-zi-lcof/solution/mian-shi-ti-39-shu-zu-zhong-chu-xian-ci-shu-chao-3/ + pub fn majority_element(mut nums: Vec) -> i32 { + let mut x = None; + let mut score = 0; + + for i in nums { + if x.is_none() { + x = Some(i); + } + + match x { + Some(s) if s == i => score += 1, + _ => score -= 1, + } + + if score == 0 { + x = None; + } + } + + x.unwrap() + } +} diff --git a/src/bin/shu-zu-zhong-de-ni-xu-dui-lcof.rs b/src/bin/shu-zu-zhong-de-ni-xu-dui-lcof.rs new file mode 100644 index 00000000..da7371b4 --- /dev/null +++ b/src/bin/shu-zu-zhong-de-ni-xu-dui-lcof.rs @@ -0,0 +1,78 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + /// 暴力解法 + pub fn reverse_pairs1(nums: Vec) -> i32 { + let mut result = 0; + + for i in 0..nums.len() { + for j in i..nums.len() { + if nums[i] > nums[j] { + result += 1; + } + } + } + + result + } + + /// 使用merge sort排序 + pub fn reverse_pairs(nums: Vec) -> i32 { + let mut new = vec![0; nums.len()]; + Self::merge_sort(&nums, &mut new) + } + + fn merge_sort(nums: &[i32], new: &mut [i32]) -> i32 { + let mut num = 0; + if nums.len() <= 1 { + if nums.len() == 1 { + new[0] = nums[0]; + } + return num; + } + + let middle = nums.len() / 2; + + let mut left_vec = vec![0; middle]; + let left = Self::merge_sort(&nums[..middle], &mut left_vec); + + let mut right_vec = vec![0; nums.len() - middle]; + let right = Self::merge_sort(&nums[middle..], &mut right_vec); + + let (mut i, mut j, mut k) = (0, 0, 0); + + loop { + match (left_vec.get(i), right_vec.get(j)) { + (Some(x), Some(y)) => { + if *x > *y { + j += 1; + num += (left_vec.len() - i) as i32; + new[k] = *y; + } else { + i += 1; + new[k] = *x; + } + } + + (Some(x), None) => { + new[k] = *x; + i += 1; + } + + (None, Some(y)) => { + new[k] = *y; + j += 1; + } + + (None, None) => break, + } + + k += 1; + } + num + left + right + } +} diff --git a/src/bin/shu-zu-zhong-shu-zi-chu-xian-de-ci-shu-ii-lcof.rs b/src/bin/shu-zu-zhong-shu-zi-chu-xian-de-ci-shu-ii-lcof.rs new file mode 100644 index 00000000..8e0f4fb9 --- /dev/null +++ b/src/bin/shu-zu-zhong-shu-zi-chu-xian-de-ci-shu-ii-lcof.rs @@ -0,0 +1,32 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn single_number(nums: Vec) -> i32 { + let mut v = [0; 32]; + + for mut i in nums { + let mut index = 0; + while i > 0 { + if i & 1 == 1 { + v[index] += 1; + } + index += 1; + i >>= 1; + } + } + + let mut result = 0; + + for (index, &value) in v.iter().enumerate() { + if value % 3 != 0 { + result |= (1 << index); + } + } + + result + } +} diff --git a/src/bin/shu-zu-zhong-shu-zi-chu-xian-de-ci-shu-lcof.rs b/src/bin/shu-zu-zhong-shu-zi-chu-xian-de-ci-shu-lcof.rs new file mode 100644 index 00000000..e92c18d3 --- /dev/null +++ b/src/bin/shu-zu-zhong-shu-zi-chu-xian-de-ci-shu-lcof.rs @@ -0,0 +1,35 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +use std::vec; + +fn main() {} + +struct Solution; + +impl Solution { + /// https://leetcode.cn/problems/shu-zu-zhong-shu-zi-chu-xian-de-ci-shu-lcof/solution/jian-zhi-offer-56-i-shu-zu-zhong-shu-zi-tykom/ + pub fn single_numbers(nums: Vec) -> Vec { + let mut x = 0; + + for &i in nums.iter() { + x ^= i; + } + + let mut m = 1; + while x & m != m { + m <<= 1; + } + + let mut v = vec![0; 2]; + + for &i in nums.iter() { + if i & m == m { + v[0] ^= i; + } else { + v[1] ^= i; + } + } + + v + } +} diff --git a/src/bin/shu-zu-zhong-zhong-fu-de-shu-zi-lcof.rs b/src/bin/shu-zu-zhong-zhong-fu-de-shu-zi-lcof.rs new file mode 100644 index 00000000..5fbb7842 --- /dev/null +++ b/src/bin/shu-zu-zhong-zhong-fu-de-shu-zi-lcof.rs @@ -0,0 +1,39 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn find_repeat_number1(nums: Vec) -> i32 { + let mut count = vec![0; nums.len()]; + for i in nums { + if count[i as usize] == 1 { + return i; + } else { + count[i as usize] = 1; + } + } + + -1 + } + + pub fn find_repeat_number(mut nums: Vec) -> i32 { + 'out: for i in 0..nums.len() { + loop { + let x = nums[i] as usize; + if i == x { + continue 'out; + } + + if nums[x] == x as i32 { + return nums[x]; + } + + nums.swap(i, x); + } + } + + -1 + } +} diff --git a/src/bin/shuffle-an-array.rs b/src/bin/shuffle-an-array.rs new file mode 100644 index 00000000..bdb113cb --- /dev/null +++ b/src/bin/shuffle-an-array.rs @@ -0,0 +1,40 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +/** + * Your Solution object will be instantiated and called as such: + * let obj = Solution::new(nums); + * let ret_1: Vec = obj.reset(); + * let ret_2: Vec = obj.shuffle(); + */ +struct Solution { + nums: Vec, +} + +/** + * `&self` means the method takes an immutable reference. + * If you need a mutable reference, change it to `&mut self` instead. + */ +impl Solution { + fn new(nums: Vec) -> Self { + Self { nums } + } + + /** Resets the array to its original configuration and return it. */ + fn reset(&self) -> Vec { + self.nums.clone() + } + + /** Returns a random shuffling of the array. */ + fn shuffle(&self) -> Vec { + use rand::Rng; + + let mut rng = rand::thread_rng(); + let mut v = self.nums.clone(); + for i in 0..self.nums.len() { + v.swap(rng.gen_range(0..self.nums.len()), i); + } + v + } +} diff --git a/src/bin/shun-shi-zhen-da-yin-ju-zhen-lcof.rs b/src/bin/shun-shi-zhen-da-yin-ju-zhen-lcof.rs new file mode 100644 index 00000000..1aa958e2 --- /dev/null +++ b/src/bin/shun-shi-zhen-da-yin-ju-zhen-lcof.rs @@ -0,0 +1,73 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +use serde::__private::de; + +fn main() {} + +struct Solution; + +enum Direction { + Right, + Down, + Left, + Up, +} + +impl Solution { + pub fn spiral_order(matrix: Vec>) -> Vec { + if matrix.is_empty() { + return vec![]; + } + + let (mut left, mut right, mut up, mut down) = (0, matrix[0].len(), 0, matrix.len()); + let mut data = Vec::with_capacity(right * down); + let (mut index1, mut index2) = (0, 0); + + let mut direction = Direction::Right; + + while left < right && up < down { + data.push(matrix[index1][index2]); + match direction { + Direction::Right => { + if index2 < right - 1 { + index2 += 1; + } else { + direction = Direction::Down; + index1 += 1; + up += 1; + } + } + + Direction::Down => { + if index1 < down - 1 { + index1 += 1; + } else { + direction = Direction::Left; + index2 -= 1; + right -= 1; + } + } + Direction::Left => { + if index2 > left + 1 { + index2 -= 1; + } else { + direction = Direction::Up; + index1 -= 1; + down -= 1; + } + } + Direction::Up => { + if index1 > up + 1 { + index1 -= 1; + } else { + direction = Direction::Right; + index2 += 1; + left += 1; + } + } + } + } + + data + } +} diff --git a/src/bin/simple-bank-system.rs b/src/bin/simple-bank-system.rs new file mode 100644 index 00000000..e82a13ab --- /dev/null +++ b/src/bin/simple-bank-system.rs @@ -0,0 +1,61 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +/** + * `&self` means the method takes an immutable reference. + * If you need a mutable reference, change it to `&mut self` instead. + */ +/** + * Your Bank object will be instantiated and called as such: + * let obj = Bank::new(balance); + * let ret_1: bool = obj.transfer(account1, account2, money); + * let ret_2: bool = obj.deposit(account, money); + * let ret_3: bool = obj.withdraw(account, money); + */ +struct Bank { + balance: Vec, +} + +impl Bank { + fn new(balance: Vec) -> Self { + Self { balance } + } + + fn transfer(&mut self, account1: i32, account2: i32, money: i64) -> bool { + if account1 as usize > self.balance.len() || account2 as usize > self.balance.len() { + return false; + } + if self.balance[account1 as usize - 1] >= money { + self.balance[account2 as usize - 1] += money; + self.balance[account1 as usize - 1] -= money; + true + } else { + false + } + } + + fn deposit(&mut self, account: i32, money: i64) -> bool { + if account as usize > self.balance.len() { + return false; + } + + self.balance[account as usize - 1] += money; + return true; + } + + fn withdraw(&mut self, account: i32, money: i64) -> bool { + if account as usize > self.balance.len() { + return false; + } + + if self.balance[account as usize - 1] >= money { + self.balance[account as usize - 1] -= money; + true + } else { + false + } + } +} diff --git a/src/bin/simplify-path.rs b/src/bin/simplify-path.rs new file mode 100644 index 00000000..7c378fe7 --- /dev/null +++ b/src/bin/simplify-path.rs @@ -0,0 +1,33 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn simplify_path(path: String) -> String { + let mut v = vec![]; + + for i in path.split('/').into_iter() { + if i != "" && i != "." { + match i { + ".." => { + v.pop(); + } + _ => v.push(i), + } + } + } + let mut s = String::new(); + if v.is_empty() { + s.push('/'); + } else { + for i in v.into_iter() { + s.push('/'); + s.push_str(i); + } + } + + s + } +} diff --git a/src/bin/single-number-ii.rs b/src/bin/single-number-ii.rs new file mode 100644 index 00000000..bf1a4220 --- /dev/null +++ b/src/bin/single-number-ii.rs @@ -0,0 +1,63 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + assert_eq!(99, Solution::single_number(vec![0, 1, 0, 1, 0, 1, 99])); + assert_eq!( + 2147483647, + Solution::single_number1(vec![ + 43, + 16, + 45, + 89, + 45, + -2147483648, + 45, + 2147483646, + -2147483647, + -2147483648, + 43, + 2147483647, + -2147483646, + -2147483648, + 89, + -2147483646, + 89, + -2147483646, + -2147483647, + 2147483646, + -2147483647, + 16, + 16, + 2147483646, + 43 + ]) + ); +} + +struct Solution; + +impl Solution { + pub fn single_number(nums: Vec) -> i32 { + let mut r = 0; + let mut seen = 0; + + for &i in nums.iter() { + r = !seen & (r ^ i); + seen = !r & (seen ^ i); + } + + r + } + + /// 使用hashset + /// 但是会溢出 + pub fn single_number1(nums: Vec) -> i32 { + let mut h = std::collections::HashSet::new(); + + for &i in nums.iter() { + h.insert(i); + } + + (h.iter().sum::() * 3 - nums.iter().sum::()) / 2 + } +} diff --git a/src/bin/single-number-iii.rs b/src/bin/single-number-iii.rs new file mode 100644 index 00000000..05eb33c6 --- /dev/null +++ b/src/bin/single-number-iii.rs @@ -0,0 +1,22 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn single_number(nums: Vec) -> Vec { + let x = nums.iter().fold(0, |x, y| x ^ y); + let y = x & -x; + let (mut type1, mut type2) = (0, 0); + for i in nums { + if i & y > 0 { + type1 ^= i; + } else { + type2 ^= i; + } + } + + vec![type1, type2] + } +} diff --git a/src/bin/single-number.rs b/src/bin/single-number.rs new file mode 100644 index 00000000..de952628 --- /dev/null +++ b/src/bin/single-number.rs @@ -0,0 +1,16 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn single_number(nums: Vec) -> i32 { + let mut r = 0; + + for &i in nums.iter() { + r ^= i; + } + r + } +} diff --git a/src/bin/sliding-window-maximum.rs b/src/bin/sliding-window-maximum.rs new file mode 100644 index 00000000..6b641242 --- /dev/null +++ b/src/bin/sliding-window-maximum.rs @@ -0,0 +1,162 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() { + println!( + "{:?}", + Solution::max_sliding_window(vec![1, 3, -1, -3, 5, 3, 6, 7], 3) + ); + println!("{:?}", Solution::max_sliding_window(vec![1], 1)); + println!("{:?}", Solution::max_sliding_window(vec![1, -1], 1)); + let a = vec![ + 7238, 9932, -7015, 6020, 2596, 6189, -7315, 3176, -7751, 7995, 3970, 7008, 4059, 9310, + -3655, -8628, 3249, 6132, 9022, 8156, 8970, 7702, -8248, 9130, -1393, -6814, -8441, 9879, + -2811, 3564, 6491, 8875, -200, 8698, -6756, -5946, 2006, 7604, 7379, -4675, 3323, -544, + 544, 130, -1171, 6535, -6825, 4471, 3580, -1876, -5201, 7337, -3992, -3277, -8251, 5427, + 8989, 4481, -298, 5049, 9762, -4932, -7561, -8209, 1343, 2338, -8612, 5181, 95, 8312, 6140, + 9449, 9283, 5812, 2348, -57, -5351, 4471, 3738, 5256, -1644, -8322, -4507, -6337, 821, + 3626, 3804, 3957, 7675, 2195, 5933, 5699, 545, -3593, -760, 199, -7339, -6963, -8857, 5111, + -2086, -4285, 5260, -6824, -7696, -3032, -1368, -6605, 2119, 5660, 850, 4834, 3333, 7193, + 6465, 1137, -7826, 3972, -4014, -8963, 6244, -5914, 7196, 8119, 4804, -1212, 4780, -5600, + 8125, -5737, -2363, -5635, 3902, 4423, -3962, 7659, -2802, 9953, 6651, 3794, -7302, 5601, + -6981, -9579, 6382, -1355, 6387, 8293, -4281, 393, 507, 3554, -85, 6148, 9009, 9994, 3835, + -8033, -985, -9909, -2869, 1453, -1824, -7902, -5402, -4205, -187, -9707, 7666, 4167, 3762, + -8791, -1256, 9682, -9714, -597, 6671, -8381, -304, -4242, -5095, 6311, -7830, -1480, + -6470, 6264, 8859, -4593, 9514, 1430, 5248, 6556, 8422, -8424, -4742, -6497, -3416, -4005, + -4213, -4945, 6129, 4473, -4092, -6352, 490, -5252, -2591, -5388, 9398, -8349, 3329, -5143, + -5446, 9031, -6319, -4679, -7013, 867, -705, 7882, 5625, 6763, 954, 897, -2191, 4859, + -4321, 4058, 2535, -1918, -9012, -2708, 500, -5448, -3478, -6758, -935, 7277, 979, -2030, + -3152, 9066, -6420, 2590, -7793, -3197, 7510, 8948, -4362, 5464, -981, 4541, -6535, -4853, + -8182, 4128, -4434, 8901, -1384, 1166, -5818, -5866, 3158, -9958, -5805, -959, 4945, -8665, + -5298, 8831, 5525, 3577, -2783, 7743, 7145, -1839, -2936, -8183, 978, 2578, -6729, -7782, + 135, 7508, 7847, + ]; + let b = [ + 9932, 9932, 9310, 9310, 9310, 9310, 9310, 9310, 9310, 9879, 9879, 9879, 9879, 9879, 9879, + 9879, 9879, 9879, 9879, 9879, 9879, 9879, 9879, 9879, 9879, 9879, 9879, 9879, 8875, 8875, + 8875, 8875, 8698, 8698, 7604, 7604, 7604, 7604, 8989, 8989, 8989, 8989, 9762, 9762, 9762, + 9762, 9762, 9762, 9762, 9762, 9762, 9762, 9762, 9762, 9762, 9762, 9762, 9762, 9762, 9762, + 9762, 9449, 9449, 9449, 9449, 9449, 9449, 9449, 9449, 9449, 9449, 9449, 9283, 7675, 7675, + 7675, 7675, 7675, 7675, 7675, 7675, 7675, 7675, 7675, 7675, 7675, 7675, 7675, 7675, 5933, + 5933, 5699, 5660, 5660, 5660, 7193, 7193, 7193, 7193, 7193, 7193, 7193, 7193, 7193, 7196, + 8119, 8119, 8119, 8119, 8119, 8125, 8125, 8125, 8125, 8125, 8125, 8125, 8125, 8125, 9953, + 9953, 9953, 9953, 9953, 9953, 9953, 9953, 9953, 9953, 9953, 9953, 9953, 9953, 9953, 9953, + 9953, 9953, 9994, 9994, 9994, 9994, 9994, 9994, 9994, 9994, 9994, 9994, 9994, 9994, 9994, + 9994, 9994, 9994, 9994, 9994, 9994, 9682, 9682, 9682, 9682, 9682, 9682, 9682, 9682, 9682, + 9682, 9682, 9682, 9682, 9682, 9682, 9682, 9682, 9682, 9514, 9514, 9514, 9514, 9514, 9514, + 9514, 9514, 9514, 9514, 9514, 9514, 9514, 9514, 9514, 8422, 9398, 9398, 9398, 9398, 9398, + 9398, 9398, 9398, 9398, 9398, 9398, 9398, 9398, 9398, 9398, 9398, 9398, 9398, 9398, 9031, + 9031, 9031, 9031, 9031, 7882, 7882, 7882, 7882, 7882, 7882, 7277, 7277, 7277, 9066, 9066, + 9066, 9066, 9066, 9066, 9066, 9066, 9066, 9066, 9066, 9066, 9066, 9066, 9066, 9066, 9066, + 9066, 9066, 8948, 8948, 8948, 8948, 8948, 8948, 8901, 8901, 8901, 8901, 8901, 8901, 8901, + 8901, 8901, 8901, 8831, 8831, 8831, 8831, 8831, 8831, 8831, 8831, 8831, + ]; + + let c = Solution::max_sliding_window(a, 19); + + assert_eq!(c, b); +} + +struct Solution; + +impl Solution { + /// 使用大顶堆 + pub fn max_sliding_window1(nums: Vec, k: i32) -> Vec { + let mut heap = vec![]; + for i in 0..k as usize { + Self::heap_insert(&mut heap, (nums[i], i)); + } + + let mut r = vec![heap[0].0]; + + for i in k as usize..nums.len() { + Self::heap_remove(&mut heap, i - k as usize); + Self::heap_insert(&mut heap, (nums[i], i)); + r.push(heap[0].0); + } + + r + } + + /// 堆插入新的元素 + fn heap_insert(heap: &mut Vec<(i32, usize)>, val: (i32, usize)) { + heap.push(val); + let mut i = heap.len() - 1; + + while i > 0 && heap[(i - 1) / 2].0 < heap[i].0 { + heap.swap(i, (i - 1) / 2); + i = (i - 1) / 2; + } + } + + /// 堆移除元素中,下标大于k的数 + /// 先找到对应的元素 + fn heap_remove(heap: &mut Vec<(i32, usize)>, k: usize) { + while !heap.is_empty() && heap[0].1 <= k { + let last = heap.len() - 1; + heap.swap(0, last); + heap.pop(); + + let mut i = 0; + loop { + match (heap.get(2 * i + 1), heap.get(2 * i + 2)) { + (Some(&left), Some(&right)) => { + if left.0 >= heap[i].0 && right.0 >= heap[i].0 { + if left.0 > right.0 { + heap.swap(i, i * 2 + 1); + i = i * 2 + 1; + } else { + heap.swap(i, i * 2 + 2); + i = i * 2 + 2; + } + } else if left.0 >= heap[i].0 { + heap.swap(i, i * 2 + 1); + i = i * 2 + 1; + } else if right.0 >= heap[i].0 { + heap.swap(i, i * 2 + 2); + i = i * 2 + 2; + } else { + break; + } + } + (Some(&left), None) if left.0 >= heap[i].0 => { + heap.swap(i, 2 * i + 1); + i = i * 2 + 1; + } + + (None, Some(&right)) if right.0 >= heap[i].0 => { + heap.swap(i, 2 * i + 2); + i = i * 2 + 2; + } + _ => break, + } + } + } + } + + pub fn max_sliding_window(nums: Vec, k: i32) -> Vec { + let mut stack = vec![]; + stack.push(0usize); + for i in 1..k as usize { + while !stack.is_empty() && nums[stack[stack.len() - 1]] <= nums[i] { + stack.pop(); + } + stack.push(i); + } + let mut r = vec![nums[stack[0]]]; + + for i in k as usize..nums.len() { + if i - k as usize + 1 > stack[0] { + stack.remove(0); + } + + while !stack.is_empty() && nums[stack[stack.len() - 1]] <= nums[i] { + stack.pop(); + } + stack.push(i); + + r.push(nums[stack[0]]); + } + + r + } +} diff --git a/src/bin/smallest-k-lcci.rs b/src/bin/smallest-k-lcci.rs new file mode 100644 index 00000000..922421bc --- /dev/null +++ b/src/bin/smallest-k-lcci.rs @@ -0,0 +1,15 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +use std::vec; + +fn main() {} + +struct Solution; + +impl Solution { + pub fn smallest_k(mut arr: Vec, k: i32) -> Vec { + arr.sort(); + + arr[..k as usize].into() + } +} diff --git a/src/bin/smallest-number-in-infinite-set.rs b/src/bin/smallest-number-in-infinite-set.rs new file mode 100644 index 00000000..dbea83ea --- /dev/null +++ b/src/bin/smallest-number-in-infinite-set.rs @@ -0,0 +1,54 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +struct SmallestInfiniteSet { + s: std::collections::BTreeSet, + latest: i32, +} + +/** + * `&self` means the method takes an immutable reference. + * If you need a mutable reference, change it to `&mut self` instead. + */ +/** + * Your SmallestInfiniteSet object will be instantiated and called as such: + * let obj = SmallestInfiniteSet::new(); + * let ret_1: i32 = obj.pop_smallest(); + * obj.add_back(num); + */ +impl SmallestInfiniteSet { + fn new() -> Self { + Self { + s: std::collections::BTreeSet::new(), + latest: 1, + } + } + + fn pop_smallest(&mut self) -> i32 { + if let Some(&x) = self.s.iter().next() { + if x < self.latest { + self.s.remove(&x); + return x; + } + } + + self.latest += 1; + self.latest - 1 + } + + fn add_back(&mut self, num: i32) { + if num >= self.latest { + return; + } + + if num == self.latest - 1 { + self.latest -= 1; + return; + } + + self.s.insert(num); + } +} diff --git a/src/bin/smallest-string-with-a-given-numeric-value.rs b/src/bin/smallest-string-with-a-given-numeric-value.rs new file mode 100644 index 00000000..1cd7c539 --- /dev/null +++ b/src/bin/smallest-string-with-a-given-numeric-value.rs @@ -0,0 +1,24 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn get_smallest_string(n: i32, k: i32) -> String { + const A: i32 = (b'z' - b'a') as _; + let mut result = vec![b'z'; n as _]; + let mut total = (A + 1) * n; + for i in 0..n as _ { + if total - k >= A { + result[i] -= A as u8; + total -= A; + } else { + result[i] -= (total - k) as u8; + break; + } + } + + String::from_utf8(result).unwrap() + } +} diff --git a/src/bin/snapshot-array.rs b/src/bin/snapshot-array.rs new file mode 100644 index 00000000..71e891c7 --- /dev/null +++ b/src/bin/snapshot-array.rs @@ -0,0 +1,64 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +/** + * `&self` means the method takes an immutable reference. + * If you need a mutable reference, change it to `&mut self` instead. + */ + +/** + * Your SnapshotArray object will be instantiated and called as such: + * let obj = SnapshotArray::new(length); + * obj.set(index, val); + * let ret_2: i32 = obj.snap(); + * let ret_3: i32 = obj.get(index, snap_id); + */ + +struct SnapshotArray { + snapshot_id: std::cell::Cell, + storage: Vec>, +} + +impl SnapshotArray { + fn new(length: i32) -> Self { + Self { + snapshot_id: std::cell::Cell::new(0), + storage: { + let mut data = Vec::with_capacity(length as usize); + for _ in 0..length { + data.push(vec![]); + } + data + }, + } + } + + fn set(&mut self, index: i32, val: i32) { + if let Some(x) = self.storage[index as usize].last_mut() { + if x.0 == self.snapshot_id.get() { + x.1 = val; + return; + } + } + + self.storage[index as usize].push((self.snapshot_id.get(), val)); + } + + fn snap(&self) -> i32 { + self.snapshot_id.set(self.snapshot_id.get() + 1); + self.snapshot_id.get() - 1 + } + + fn get(&self, index: i32, snap_id: i32) -> i32 { + let s = self.storage.get(index as usize).unwrap(); + let i = s.partition_point(|x| x.0 <= snap_id); + if i > 0 { + s[i - 1].1 + } else { + 0 + } + } +} diff --git a/src/bin/sort-colors.rs b/src/bin/sort-colors.rs new file mode 100644 index 00000000..7b05e88f --- /dev/null +++ b/src/bin/sort-colors.rs @@ -0,0 +1,32 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + let mut v = vec![2, 0, 2, 1, 1, 1, 1, 1, 0, 2, 2, 2, 2, 0, 0, 2, 1, 0]; + Solution::sort_colors(&mut v); + + let mut v = vec![1, 0]; + Solution::sort_colors(&mut v); +} + +struct Solution; + +impl Solution { + pub fn sort_colors(nums: &mut Vec) { + let (mut p1, mut p2, mut cursor) = (0, 0, 0); + + while cursor < nums.len() { + if nums[cursor] == 0 { + nums.swap(cursor, p1); + if p1 < p2 { + nums.swap(cursor, p2); + } + p2 += 1; + p1 += 1; + } else if nums[cursor] == 1 { + nums.swap(cursor, p2); + p2 += 1; + } + cursor += 1; + } + } +} diff --git a/src/bin/sort-integers-by-the-number-of-1-bits.rs b/src/bin/sort-integers-by-the-number-of-1-bits.rs new file mode 100644 index 00000000..dfb829ab --- /dev/null +++ b/src/bin/sort-integers-by-the-number-of-1-bits.rs @@ -0,0 +1,18 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn sort_by_bits(arr: Vec) -> Vec { + let mut arr = arr; + + arr.sort_by(|x, y| match x.count_ones().cmp(&y.count_ones()) { + std::cmp::Ordering::Equal => x.cmp(y), + i => i, + }); + + arr + } +} diff --git a/src/bin/sort-integers-by-the-power-value.rs b/src/bin/sort-integers-by-the-power-value.rs new file mode 100644 index 00000000..00598be6 --- /dev/null +++ b/src/bin/sort-integers-by-the-power-value.rs @@ -0,0 +1,40 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn get_kth(lo: i32, hi: i32, k: i32) -> i32 { + let mut hash = std::collections::HashMap::new(); + let mut s = (lo..=hi).collect::>(); + s.sort_unstable_by(|x, y| { + match Self::weight(*x, &mut hash).cmp(&Self::weight(*y, &mut hash)) { + std::cmp::Ordering::Equal => x.cmp(y), + m => m, + } + }); + + s[k as usize - 1] + } + + fn weight(mut num: i32, hash: &mut std::collections::HashMap) -> i32 { + let mut weight = 0; + while num != 1 { + if let Some(&x) = hash.get(&num) { + weight += x; + break; + } + + if num % 2 == 0 { + num /= 2; + } else { + num = 3 * num + 1; + } + + weight += 1; + } + hash.insert(num, weight); + weight + } +} diff --git a/src/bin/sort-list.rs b/src/bin/sort-list.rs new file mode 100644 index 00000000..117583eb --- /dev/null +++ b/src/bin/sort-list.rs @@ -0,0 +1,84 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +// Definition for singly-linked list. +#[derive(PartialEq, Eq, Clone, Debug)] +pub struct ListNode { + pub val: i32, + pub next: Option>, +} + +impl ListNode { + #[inline] + fn new(val: i32) -> Self { + ListNode { next: None, val } + } +} + +impl Solution { + /// 归并排序 + pub fn sort_list(mut head: Option>) -> Option> { + let mut length = 0; + let mut ptr = head.as_ref(); + + if ptr.is_some() { + ptr = ptr.unwrap().next.as_ref(); + length += 1; + } + + Solution::sort(head, length) + } + + pub fn sort(mut head: Option>, length: usize) -> Option> { + if head.is_none() { + return None; + } + + if head.as_ref().unwrap().next.is_none() { + return head; + } + + let mut middle = head.as_mut(); + + for _ in 0..length / 2 { + middle = middle.unwrap().next.as_mut(); + } + + let mut r1 = Solution::sort_list(middle.unwrap().next.take()); + let mut r2 = Solution::sort_list(head); + + let mut result = Some(Box::new(ListNode::new(-1i32))); + let mut current = result.as_mut(); + loop { + match (r1, r2) { + (Some(mut x1), Some(mut x2)) => { + if x1.val < x2.val { + r2 = Some(x2); + r1 = x1.next.take(); + current.as_mut().unwrap().next = Some(x1); + } else { + r1 = Some(x1); + r2 = x2.next.take(); + current.as_mut().unwrap().next = Some(x2); + } + + current = current.unwrap().next.as_mut(); + } + (Some(x1), None) => { + current.unwrap().next = Some(x1); + break; + } + (None, Some(x2)) => { + current.unwrap().next = Some(x2); + break; + } + _ => break, + } + } + + result.map(|mut x| x.next.take()).unwrap() + } +} diff --git a/src/bin/sort-the-matrix-diagonally.rs b/src/bin/sort-the-matrix-diagonally.rs new file mode 100644 index 00000000..18c5fc7b --- /dev/null +++ b/src/bin/sort-the-matrix-diagonally.rs @@ -0,0 +1,57 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + let a = vec![vec![3, 3, 1, 1], vec![2, 2, 1, 2], vec![1, 1, 1, 2]]; + let b = Solution::diagonal_sort(a); + println!("{:?}", b); + + let a = vec![ + vec![11, 25, 66, 1, 69, 7], + vec![23, 55, 17, 45, 15, 52], + vec![75, 31, 36, 44, 58, 8], + vec![22, 27, 33, 25, 68, 4], + vec![84, 28, 14, 11, 5, 50], + ]; + let b = Solution::diagonal_sort(a); + println!("{:?}", b); +} + +struct Solution; + +impl Solution { + pub fn diagonal_sort(mut mat: Vec>) -> Vec> { + if mat.is_empty() { + return mat; + } + + for i in 0..mat[0].len() { + Self::bubble_sort(&mut mat, 0, i); + } + + for i in 1..mat.len() { + Self::bubble_sort(&mut mat, i, 0); + } + + mat + } + + pub fn bubble_sort(mat: &mut Vec>, x: usize, y: usize) { + let (mut l1, mut l2) = (mat.len() - 1, mat[0].len() - 1); + while l1 > x && l2 > y { + let (mut x1, mut y1) = (x + 1, y + 1); + + while x1 <= l1 && y1 <= l2 { + if mat[x1][y1] < mat[x1 - 1][y1 - 1] { + let a = mat[x1][y1]; + mat[x1][y1] = mat[x1 - 1][y1 - 1]; + mat[x1 - 1][y1 - 1] = a; + } + x1 += 1; + y1 += 1; + } + + l1 -= 1; + l2 -= 1; + } + } +} diff --git a/src/bin/special-array-i.rs b/src/bin/special-array-i.rs new file mode 100644 index 00000000..2f0c3487 --- /dev/null +++ b/src/bin/special-array-i.rs @@ -0,0 +1,20 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn is_array_special(nums: Vec) -> bool { + let mut i = nums[0] % 2; + for x in nums[1..].into_iter() { + if x % 2 == i { + return false; + } + + i = x % 2; + } + + true + } +} diff --git a/src/bin/special-array-ii.rs b/src/bin/special-array-ii.rs new file mode 100644 index 00000000..d8fb29ec --- /dev/null +++ b/src/bin/special-array-ii.rs @@ -0,0 +1,33 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + /// 前缀和 + /// 对于prefix_sum. 如果nums[i] 与 nums[i-1]的奇偶性不同,则prefix_sum[i] = 0, 否则为1 + /// 因此如果 nums[i] ~ nums[j] 是特殊子数组,则prefix_sum[i] == prefix_sum[j] + pub fn is_array_special(nums: Vec, queries: Vec>) -> Vec { + let mut prefix_sum = vec![0]; + + for i in 1..nums.len() { + if nums[i] % 2 != nums[i - 1] % 2 { + prefix_sum.push(prefix_sum[i - 1]); + } else { + prefix_sum.push(prefix_sum[i - 1] + 1); + } + } + + let mut result = vec![]; + for i in queries { + if prefix_sum[i[0] as usize] == prefix_sum[i[1] as usize] { + result.push(true); + } else { + result.push(false); + } + } + + result + } +} diff --git a/src/bin/spiral-matrix-iii.rs b/src/bin/spiral-matrix-iii.rs new file mode 100644 index 00000000..e27a093a --- /dev/null +++ b/src/bin/spiral-matrix-iii.rs @@ -0,0 +1,61 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + println!("{:?}", Solution::spiral_matrix_iii(5, 4, 0, 2)); + println!("{}", "[[0, 2], [0, 3], [1, 3], [1, 2], [1, 1], [0, 1], [2, 3], [2, 2], [2, 1], [2, 0], [1, 0], [0, 0], [3, 3], [3, 2], [3, 1], [3, 0], [4, 3], [4, 2], [4, 1], [4, 0]]") +} + +struct Solution; + +impl Solution { + // 其实就是以(r0, c0)为中心画正方形,每个正方形的边长加2 + pub fn spiral_matrix_iii(r: i32, c: i32, r0: i32, c0: i32) -> Vec> { + let mut result = vec![]; + result.push(vec![r0, c0]); + let mut start = (r0, c0); + + let mut length = 1; // 起始的边长的一半为1 + while r0 - length >= 0 || r0 + length < r || c0 - length >= 0 || c0 + length < c { + start.1 += 1; + while r0 + length > start.0 { + if Self::check(r, c, start.0, start.1) { + result.push(vec![start.0, start.1]); + } + start.0 += 1; + } + + while c0 - length < start.1 { + if Self::check(r, c, start.0, start.1) { + result.push(vec![start.0, start.1]); + } + start.1 -= 1; + } + + while r0 - length < start.0 { + if Self::check(r, c, start.0, start.1) { + result.push(vec![start.0, start.1]); + } + start.0 -= 1; + } + + while c0 + length > start.1 { + if Self::check(r, c, start.0, start.1) { + result.push(vec![start.0, start.1]); + } + start.1 += 1; + } + + if Self::check(r, c, start.0, start.1) { + result.push(vec![start.0, start.1]); + } + + length += 1; + } + + result + } + + fn check(r: i32, c: i32, r1: i32, c1: i32) -> bool { + r1 >= 0 && r1 < r && c1 >= 0 && c1 < c + } +} diff --git a/src/bin/spiral-matrix.rs b/src/bin/spiral-matrix.rs new file mode 100644 index 00000000..48aa0643 --- /dev/null +++ b/src/bin/spiral-matrix.rs @@ -0,0 +1,71 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +enum Direction { + Right, + Down, + Left, + Up, +} + +impl Solution { + pub fn spiral_order(matrix: Vec>) -> Vec { + if matrix.is_empty() { + return vec![]; + } + + let (mut left, mut right, mut up, mut down) = (0, matrix[0].len(), 0, matrix.len()); + let mut data = Vec::with_capacity(right * down); + let (mut index1, mut index2) = (0, 0); + + let mut direction = Direction::Right; + + while left < right && up < down { + data.push(matrix[index1][index2]); + match direction { + Direction::Right => { + if index2 < right - 1 { + index2 += 1; + } else { + direction = Direction::Down; + index1 += 1; + up += 1; + } + } + + Direction::Down => { + if index1 < down - 1 { + index1 += 1; + } else { + direction = Direction::Left; + index2 -= 1; + right -= 1; + } + } + Direction::Left => { + if index2 > left { + index2 -= 1; + } else { + direction = Direction::Up; + index1 -= 1; + down -= 1; + } + } + Direction::Up => { + if index1 > up { + index1 -= 1; + } else { + direction = Direction::Right; + index2 += 1; + left += 1; + } + } + } + } + + data + } +} diff --git a/src/bin/split-a-string-in-balanced-strings.rs b/src/bin/split-a-string-in-balanced-strings.rs new file mode 100644 index 00000000..f0e55fa1 --- /dev/null +++ b/src/bin/split-a-string-in-balanced-strings.rs @@ -0,0 +1,31 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn balanced_string_split(s: String) -> i32 { + let mut l_num = 0; + let mut r_num = 0; + let mut num = 0; + + for i in s.chars().into_iter() { + if i == 'L' { + l_num += 1; + } + + if i == 'R' { + r_num += 1; + } + + if l_num == r_num { + num += 1; + l_num = 0; + r_num = 0; + } + } + + num + } +} diff --git a/src/bin/split-strings-by-separator.rs b/src/bin/split-strings-by-separator.rs new file mode 100644 index 00000000..e5a4f75c --- /dev/null +++ b/src/bin/split-strings-by-separator.rs @@ -0,0 +1,20 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn split_words_by_separator(words: Vec, separator: char) -> Vec { + let mut result = vec![]; + for i in words { + result.extend( + i.split(separator) + .filter(|x| !x.is_empty()) + .map(|x| x.to_string()), + ); + } + + result + } +} diff --git a/src/bin/split-with-minimum-sum.rs b/src/bin/split-with-minimum-sum.rs new file mode 100644 index 00000000..7eb77ac7 --- /dev/null +++ b/src/bin/split-with-minimum-sum.rs @@ -0,0 +1,34 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn split_num(num: i32) -> i32 { + let mut num = num; + let mut v = [0; 10]; + while num > 0 { + v[(num % 10) as usize] += 1; + num /= 10; + } + let (mut l, mut r) = (0, 0); + let mut i = 1; + let mut f = false; + while i < v.len() { + if v[i] > 0 { + if f { + l = l * 10 + i as i32; + } else { + r = r * 10 + i as i32; + } + v[i] -= 1; + f = !f; + } else { + i += 1; + } + } + + l + r + } +} diff --git a/src/bin/sqrtx.rs b/src/bin/sqrtx.rs new file mode 100644 index 00000000..2d0969af --- /dev/null +++ b/src/bin/sqrtx.rs @@ -0,0 +1,18 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn my_sqrt(x: i32) -> i32 { + let s = x as f64; + let mut x1 = x as f64; + + while (s - x1 * x1).abs() > 0.1 { + x1 = (s / x1 + x1) / 2f64; + } + + x1 as i32 + } +} diff --git a/src/bin/squares-of-a-sorted-array.rs b/src/bin/squares-of-a-sorted-array.rs new file mode 100644 index 00000000..4dbc1cfb --- /dev/null +++ b/src/bin/squares-of-a-sorted-array.rs @@ -0,0 +1,31 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn sorted_squares(nums: Vec) -> Vec { + let mut r = vec![0; nums.len()]; + let mut k = nums.len() - 1; + let mut nums = &nums[..]; + + while !nums.is_empty() { + if nums.len() == 1 { + r[k] = nums[0].pow(2); + nums = &nums[1..]; + } else { + if nums[0].abs() > nums[nums.len() - 1].abs() { + r[k] = nums[0].pow(2); + nums = &nums[1..]; + } else { + r[k] = nums[nums.len() - 1].pow(2); + nums = &nums[..nums.len() - 1]; + } + } + + k -= 1; + } + r + } +} diff --git a/src/bin/stock-price-fluctuation.rs b/src/bin/stock-price-fluctuation.rs new file mode 100644 index 00000000..8764d992 --- /dev/null +++ b/src/bin/stock-price-fluctuation.rs @@ -0,0 +1,64 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +struct StockPrice { + current: i32, + + /// timestamp: price + time_map: std::collections::HashMap, + /// price: 次数 + price_count: std::collections::BTreeMap, +} + +/** + * `&self` means the method takes an immutable reference. + * If you need a mutable reference, change it to `&mut self` instead. + */ +/** + * Your StockPrice object will be instantiated and called as such: + * let obj = StockPrice::new(); + * obj.update(timestamp, price); + * let ret_2: i32 = obj.current(); + * let ret_3: i32 = obj.maximum(); + * let ret_4: i32 = obj.minimum(); + */ + +impl StockPrice { + fn new() -> Self { + StockPrice { + current: 0, + time_map: Default::default(), + price_count: Default::default(), + } + } + + fn update(&mut self, timestamp: i32, price: i32) { + self.current = self.current.max(timestamp); + if let Some(x) = self.time_map.insert(timestamp, price) { + *self.price_count.get_mut(&x).unwrap() -= 1; + if self.price_count[&x] == 0 { + self.price_count.remove(&x); + } + } + + self.price_count + .entry(price) + .and_modify(|x| *x += 1) + .or_insert(1); + } + + fn current(&self) -> i32 { + self.time_map[&self.current] + } + + fn maximum(&self) -> i32 { + *self.price_count.iter().rev().next().unwrap().0 + } + + fn minimum(&self) -> i32 { + *self.price_count.iter().next().unwrap().0 + } +} diff --git a/src/bin/stone-game-vi.rs b/src/bin/stone-game-vi.rs new file mode 100644 index 00000000..34ce3778 --- /dev/null +++ b/src/bin/stone-game-vi.rs @@ -0,0 +1,32 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn stone_game_vi(alice_values: Vec, bob_values: Vec) -> i32 { + let mut x: Vec<_> = alice_values + .into_iter() + .zip(bob_values.into_iter()) + .map(|(x, y)| (x + y, x, y)) + .collect(); + + x.sort_unstable_by(|x, y| x.cmp(y).reverse()); + + let (mut a_score, mut b_score) = (0, 0); + for i in 0..x.len() { + if i % 2 == 0 { + a_score += x[i].1; + } else { + b_score += x[i].2; + } + } + + match a_score.cmp(&b_score) { + std::cmp::Ordering::Equal => 0, + std::cmp::Ordering::Greater => 1, + std::cmp::Ordering::Less => -1, + } + } +} diff --git a/src/bin/string-rotation-lcci.rs b/src/bin/string-rotation-lcci.rs new file mode 100644 index 00000000..745fb833 --- /dev/null +++ b/src/bin/string-rotation-lcci.rs @@ -0,0 +1,20 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +use std::ops::Add; + +fn main() {} + +struct Solution; + +impl Solution { + pub fn is_fliped_string(s1: String, s2: String) -> bool { + use std::ops::Add; + + if s1.len() != s2.len() { + return false; + } + + let mut new_s1 = s1.clone(); + new_s1.add(s1.as_str()).contains(&s2) + } +} diff --git a/src/bin/string-to-integer-atoi.rs b/src/bin/string-to-integer-atoi.rs new file mode 100644 index 00000000..fe5f3ff7 --- /dev/null +++ b/src/bin/string-to-integer-atoi.rs @@ -0,0 +1,72 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + assert_eq!(42, Solution::my_atoi("42".to_string())); + assert_eq!(-42, Solution::my_atoi(" -42".to_string())); + assert_eq!(4193, Solution::my_atoi("4193 with words".to_string())); + assert_eq!(0, Solution::my_atoi("words and 987".to_string())); + assert_eq!(-2147483648, Solution::my_atoi("-91283472332".to_string())); + assert_eq!(0, Solution::my_atoi(" ++1".to_string())); + assert_eq!(2147483647, Solution::my_atoi("21474836460".to_string())); + assert_eq!(0, Solution::my_atoi("-+12".to_string())); +} + +struct Solution; + +impl Solution { + pub fn my_atoi(s: String) -> i32 { + // 丢弃无用的前导空格 + let s = s.trim_start_matches(" "); + // 判断是否是字母开头或者.开头 + if s.starts_with(char::is_alphabetic) || s.starts_with(".") { + return 0; + } + + // 结果、是否为正数、是否溢出、是否开始计算 + let (mut result, mut is_positive, mut is_overflow) = (0, true, false); + + for (i, v) in s.bytes().enumerate() { + if i == 0 { + if v == b'-' { + is_positive = false; + } else if v == b'+' { + is_positive = true; + } else { + result = (v - b'0') as i32; + } + } else { + if v < b'0' || v > b'9' { + break; + } + + let s = result.overflowing_mul(10); + if s.1 { + is_overflow = true; + break; + } + + let s = s.0.overflowing_add((v - b'0') as i32); + if s.1 { + is_overflow = true; + break; + } + + result = s.0; + } + } + + if is_positive { + if is_overflow { + std::i32::MAX + } else { + result + } + } else { + if is_overflow { + std::i32::MIN + } else { + result * -1 + } + } + } +} diff --git a/src/bin/string-to-url-lcci.rs b/src/bin/string-to-url-lcci.rs new file mode 100644 index 00000000..8a426826 --- /dev/null +++ b/src/bin/string-to-url-lcci.rs @@ -0,0 +1,20 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn replace_spaces(s: String, length: i32) -> String { + let mut s1 = String::new(); + for i in s.chars().take(length as usize) { + if i == ' ' { + s1.push_str("%20"); + } else { + s1.push(i); + } + } + + s1 + } +} diff --git a/src/bin/student-attendance-record-i.rs b/src/bin/student-attendance-record-i.rs new file mode 100644 index 00000000..2370757c --- /dev/null +++ b/src/bin/student-attendance-record-i.rs @@ -0,0 +1,32 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn check_record(s: String) -> bool { + let (mut a_count, mut l_count) = (0, 0); + let vec = s.into_bytes(); + + for (i, &v) in vec.iter().enumerate() { + if v == b'A' { + a_count += 1; + if a_count > 1 { + return false; + } + } + + if vec[i] == b'L' { + l_count += 1; + if l_count > 2 { + return false; + } + } else { + l_count = 0; + } + } + + true + } +} diff --git a/src/bin/subarray-sum-equals-k.rs b/src/bin/subarray-sum-equals-k.rs new file mode 100644 index 00000000..6af80ca9 --- /dev/null +++ b/src/bin/subarray-sum-equals-k.rs @@ -0,0 +1,27 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + assert_eq!( + 39, + Solution::subarray_sum(vec![0, 0, 0, 0, 1, -1, 0, 0, 1, 1, 0, 0, 2, -2, 2], 2) + ); +} + +struct Solution; + +impl Solution { + pub fn subarray_sum(nums: Vec, k: i32) -> i32 { + let mut sums = std::collections::HashMap::::new(); + sums.insert(0, 1); + let mut sum = 0; + let mut count = 0; + for &i in nums.iter() { + sum += i; + if let Some(s) = sums.get(&(sum - k)) { + count += *s + } + sums.entry(sum).and_modify(|x| *x += 1).or_insert(1); + } + count + } +} diff --git a/src/bin/subdomain-visit-count.rs b/src/bin/subdomain-visit-count.rs index b9e722df..0c7573d3 100644 --- a/src/bin/subdomain-visit-count.rs +++ b/src/bin/subdomain-visit-count.rs @@ -1,9 +1,20 @@ +#![allow(dead_code, unused, unused_variables)] + fn main() { - println!("{:?}", Solution::subdomain_visits( - vec!["900 google.mail.com", "50 yahoo.com", "1 intel.mail.com", "5 wiki.org"]. - into_iter(). - map(|x| x.to_string()).collect() - )); + println!( + "{:?}", + Solution::subdomain_visits( + vec![ + "900 google.mail.com", + "50 yahoo.com", + "1 intel.mail.com", + "5 wiki.org" + ] + .into_iter() + .map(|x| x.to_string()) + .collect() + ) + ); } struct Solution; @@ -17,15 +28,19 @@ impl Solution { let num = split[0].parse::().unwrap(); let url = split[1]; - m.entry(String::from(url)).and_modify(|x| *x += num).or_insert(num); + m.entry(String::from(url)) + .and_modify(|x| *x += num) + .or_insert(num); for (index, v) in url.as_bytes().iter().enumerate() { if *v == '.' as u8 { - m.entry(url[index+1..].to_string()).and_modify(|x| *x += num).or_insert(num); + m.entry(url[index + 1..].to_string()) + .and_modify(|x| *x += num) + .or_insert(num); } } } m.iter().map(|(x, y)| format!("{} {}", y, x)).collect() } -} \ No newline at end of file +} diff --git a/src/bin/subsets.rs b/src/bin/subsets.rs new file mode 100644 index 00000000..3646cf0b --- /dev/null +++ b/src/bin/subsets.rs @@ -0,0 +1,32 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn subsets(nums: Vec) -> Vec> { + let mut l = Self::s(&nums[..]); + l.push(vec![]); + l + } + + fn s(nums: &[i32]) -> Vec> { + let mut r = vec![]; + if nums.len() == 0 { + return r; + } + + let x = nums[0]; + r.push(vec![x]); + for j in Self::s(&nums[1..]) { + let mut m = Vec::with_capacity(1 + j.len()); + m.push(x); + m.extend_from_slice(&j[..]); + r.push(j); + r.push(m); + } + + r + } +} diff --git a/src/bin/substring-with-concatenation-of-all-words.rs b/src/bin/substring-with-concatenation-of-all-words.rs new file mode 100644 index 00000000..28d0eae3 --- /dev/null +++ b/src/bin/substring-with-concatenation-of-all-words.rs @@ -0,0 +1,80 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +use std::vec; + +fn main() { + assert_eq!( + Solution::find_substring("aaaaaa".into(), vec!["a".into(), "a".into()]), + vec![0, 1, 2, 3, 4] + ); + + assert_eq!( + Solution::find_substring( + "barfoothefoobarman".into(), + vec!["foo".into(), "bar".into()] + ), + vec![0, 9] + ); + + assert_eq!( + Solution::find_substring( + "wordgoodgoodgoodbestword".into(), + vec!["word".into(), "good".into(), "best".into(), "word".into()] + ), + vec![] + ); + + assert_eq!( + Solution::find_substring( + "barfoofoobarthefoobarman".into(), + vec!["bar".into(), "foo".into(), "the".into()] + ), + vec![6, 9, 12] + ); +} + +struct Solution; + +impl Solution { + /// 先对words的单词计数,使用hashmap,m + /// 遍历s的下标为i,获取words单词长度的子字符串,如果在m存在,如果数量大于1则数量-1,如果数量为1则从m中删除此字符串,如果不存在则说明i为起始的子字符串不满足条件 + /// 注意:每次遍历时都要生成一个新的m + pub fn find_substring(s: String, words: Vec) -> Vec { + let word_len = words[0].len(); + let sub_string_len = words.len() * word_len; + let mut ans = vec![]; + + if s.len() < sub_string_len { + return ans; + } + + let mut map = std::collections::HashMap::new(); + + for i in words.iter() { + map.entry(&i[..]).and_modify(|x| *x += 1).or_insert(1i32); + } + + 'Loop: for i in 0..=s.len() - sub_string_len { + let mut m = map.clone(); + + for j in (i..i + sub_string_len).step_by(word_len) { + match m.get_mut(&s[j..j + word_len]) { + Some(x) => { + if *x > 1 { + *x -= 1 + } else if *x == 1 { + m.remove(&s[j..j + word_len]); + } + } + None => continue 'Loop, + } + } + + if m.is_empty() { + ans.push(i as i32); + } + } + + ans + } +} diff --git a/src/bin/subtract-the-product-and-sum-of-digits-of-an-integer.rs b/src/bin/subtract-the-product-and-sum-of-digits-of-an-integer.rs new file mode 100644 index 00000000..81a0388c --- /dev/null +++ b/src/bin/subtract-the-product-and-sum-of-digits-of-an-integer.rs @@ -0,0 +1,20 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn subtract_product_and_sum(mut n: i32) -> i32 { + let mut r = 1; + let mut s = 0; + + while n > 0 { + r *= (n % 10); + s += (n % 10); + n /= 10; + } + + r - s + } +} diff --git a/src/bin/subtree-of-another-tree.rs b/src/bin/subtree-of-another-tree.rs new file mode 100644 index 00000000..2969cd2c --- /dev/null +++ b/src/bin/subtree-of-another-tree.rs @@ -0,0 +1,75 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +// Definition for a binary tree node. +#[derive(Debug, PartialEq, Eq)] +pub struct TreeNode { + pub val: i32, + pub left: Option>>, + pub right: Option>>, +} + +impl TreeNode { + #[inline] + pub fn new(val: i32) -> Self { + TreeNode { + val, + left: None, + right: None, + } + } +} + +use std::cell::RefCell; +use std::rc::Rc; +impl Solution { + pub fn is_subtree( + root: Option>>, + sub_root: Option>>, + ) -> bool { + if root.is_none() || sub_root.is_none() { + return root == sub_root; + } + + Self::check(root.clone(), sub_root.clone()) + || Self::is_subtree( + root.clone().and_then(|x| x.borrow().left.clone()), + sub_root.clone(), + ) + || Self::is_subtree( + root.clone().and_then(|x| x.borrow().right.clone()), + sub_root.clone(), + ) + } + + pub fn check( + root: Option>>, + sub_root: Option>>, + ) -> bool { + if root.is_none() && sub_root.is_none() { + return true; + } else if root.is_none() && sub_root.is_some() { + return false; + } else if root.is_some() && sub_root.is_none() { + return false; + } + + let v1 = root.clone().unwrap().borrow().val; + let v2 = sub_root.clone().unwrap().borrow().val; + + if v1 != v2 { + return false; + } + + Self::check( + root.clone().and_then(|x| x.borrow().left.clone()), + sub_root.clone().and_then(|x| x.borrow().left.clone()), + ) && Self::check( + root.clone().and_then(|x| x.borrow().right.clone()), + sub_root.clone().and_then(|x| x.borrow().right.clone()), + ) + } +} diff --git a/src/bin/successful-pairs-of-spells-and-potions.rs b/src/bin/successful-pairs-of-spells-and-potions.rs new file mode 100644 index 00000000..61762eb2 --- /dev/null +++ b/src/bin/successful-pairs-of-spells-and-potions.rs @@ -0,0 +1,50 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + let s = Solution::successful_pairs(vec![5, 1, 3], vec![1, 2, 3, 4, 5], 7); + println!("{s:?}"); + + let s = Solution::successful_pairs(vec![3, 1, 2], vec![8, 5, 8], 16); + println!("{s:?}"); + let s = Solution::successful_pairs(vec![1, 2, 3, 4, 5, 6, 7], vec![1, 2, 3, 4, 5, 6, 7], 25); + println!("{s:?}"); +} + +struct Solution; + +impl Solution { + pub fn successful_pairs(spells: Vec, potions: Vec, success: i64) -> Vec { + let mut nums = vec![0; spells.len()]; + + let mut potions = potions; + potions.sort(); + + for (i, v) in spells.into_iter().enumerate() { + let (mut start, mut end) = (0, potions.len() - 1); + let min = if success % v as i64 == 0 { + success / v as i64 + } else { + success / v as i64 + 1 + }; + + while start <= end && (start + end) / 2 < potions.len() { + let middile = (start + end) / 2; + + if potions[middile] as i64 >= min { + if middile == 0 { + nums[i] = potions.len() as i32; + break; + } else if (potions[middile - 1] as i64) < min { + nums[i] = (potions.len() - middile) as i32; + break; + } else { + end = middile; + } + } else { + start = middile + 1; + } + } + } + nums + } +} diff --git a/src/bin/sudoku-solver.rs b/src/bin/sudoku-solver.rs new file mode 100644 index 00000000..ab068d30 --- /dev/null +++ b/src/bin/sudoku-solver.rs @@ -0,0 +1,83 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() { + let mut v = vec![ + vec!['5', '3', '.', '.', '7', '.', '.', '.', '.'], + vec!['6', '.', '.', '1', '9', '5', '.', '.', '.'], + vec!['.', '9', '8', '.', '.', '.', '.', '6', '.'], + vec!['8', '.', '.', '.', '6', '.', '.', '.', '3'], + vec!['4', '.', '.', '8', '.', '3', '.', '.', '1'], + vec!['7', '.', '.', '.', '2', '.', '.', '.', '6'], + vec!['.', '6', '.', '.', '.', '.', '2', '8', '.'], + vec!['.', '.', '.', '4', '1', '9', '.', '.', '5'], + vec!['.', '.', '.', '.', '8', '.', '.', '7', '9'], + ]; + + Solution::solve_sudoku(&mut v); + + for i in v { + println!("{i:?}"); + } +} + +struct Solution; + +impl Solution { + /// 暴力解法,挨个枚举就完事 + pub fn solve_sudoku(board: &mut Vec>) { + Self::rec(board, (0, 0)); + } + + pub fn rec(board: &mut Vec>, start: (usize, usize)) -> bool { + if start.0 > 8 || start.1 > 8 { + return false; + } + + if start.0 == 8 && start.1 == 8 && board[start.0][start.1] != '.' { + return true; + } + + // 下一个坐标 + let mut index = if start.1 == 8 { + (start.0 + 1, 0) + } else { + (start.0, start.1 + 1) + }; + + if board[start.0][start.1] != '.' { + return Self::rec(board, index); + } + + 'Loop: for value in '1'..='9' { + // 检查行和列 + for x in 0..9 { + if board[start.0][x] == value { + continue 'Loop; + } + + if board[x][start.1] == value { + continue 'Loop; + } + } + + // 检查四周 + for i in start.0 / 3 * 3..start.0 / 3 * 3 + 3 { + for j in start.1 / 3 * 3..start.1 / 3 * 3 + 3 { + if board[i][j] == value { + continue 'Loop; + } + } + } + + board[start.0][start.1] = value; + + if !Solution::rec(board, index) { + board[start.0][start.1] = '.'; + } else { + return true; + } + } + + false + } +} diff --git a/src/bin/sum-in-a-matrix.rs b/src/bin/sum-in-a-matrix.rs new file mode 100644 index 00000000..fb287dfd --- /dev/null +++ b/src/bin/sum-in-a-matrix.rs @@ -0,0 +1,26 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn matrix_sum(mut nums: Vec>) -> i32 { + for i in nums.iter_mut() { + i.sort_by(|a, b| a.cmp(b)); + } + + let mut result = 0; + + for i in 0..nums[0].len() { + let mut max = 0; + for j in 0..nums.len() { + max = max.max(nums[j][i]); + } + + result += max; + } + + result + } +} diff --git a/src/bin/sum-lists-lcci.rs b/src/bin/sum-lists-lcci.rs new file mode 100644 index 00000000..7e1cb0c0 --- /dev/null +++ b/src/bin/sum-lists-lcci.rs @@ -0,0 +1,52 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +// Definition for singly-linked list. +#[derive(PartialEq, Eq, Clone, Debug)] +pub struct ListNode { + pub val: i32, + pub next: Option>, +} + +impl ListNode { + #[inline] + fn new(val: i32) -> Self { + ListNode { next: None, val } + } +} +impl Solution { + pub fn add_two_numbers( + l1: Option>, + l2: Option>, + ) -> Option> { + let mut result = ListNode::new(0); + let mut current = &mut result; + let mut s = 0; // 进制 + let (mut l1, mut l2) = (l1, l2); + + while l1.is_some() || l2.is_some() { + let a = if let Some(mut x) = l1 { + l1 = x.next.take(); + x.val + } else { + 0 + }; + + let b = if let Some(mut x) = l2 { + l2 = x.next.take(); + x.val + } else { + 0 + }; + let s1 = (a + b + s) / 10; + let v = (a + b + s) % 10; + s = s1; + current = current.next.insert(Box::new(ListNode::new(v))); + } + + result.next.take() + } +} diff --git a/src/bin/sum-multiples.rs b/src/bin/sum-multiples.rs new file mode 100644 index 00000000..c732f6f4 --- /dev/null +++ b/src/bin/sum-multiples.rs @@ -0,0 +1,12 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn sum_of_multiples(n: i32) -> i32 { + let f = |y: i32| -> i32 { (y + (n / y) * y) * (n / y) / 2 }; + f(3) + f(5) + f(7) - f(3 * 5) - f(3 * 7) - f(5 * 7) + f(3 * 5 * 7) + } +} diff --git a/src/bin/sum-of-digits-in-base-k.rs b/src/bin/sum-of-digits-in-base-k.rs new file mode 100644 index 00000000..f28fe372 --- /dev/null +++ b/src/bin/sum-of-digits-in-base-k.rs @@ -0,0 +1,19 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn sum_base(n: i32, k: i32) -> i32 { + let mut sum = 0; + let mut n = n; + + while n > 0 { + sum += n % k; + n = n / k; + } + + sum + } +} diff --git a/src/bin/sum-of-left-leaves.rs b/src/bin/sum-of-left-leaves.rs new file mode 100644 index 00000000..a9b0f02f --- /dev/null +++ b/src/bin/sum-of-left-leaves.rs @@ -0,0 +1,49 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +// Definition for a binary tree node. +#[derive(Debug, PartialEq, Eq)] +pub struct TreeNode { + pub val: i32, + pub left: Option>>, + pub right: Option>>, +} + +impl TreeNode { + #[inline] + pub fn new(val: i32) -> Self { + TreeNode { + val, + left: None, + right: None, + } + } +} + +use std::cell::RefCell; +use std::rc::Rc; + +impl Solution { + pub fn sum_of_left_leaves(root: Option>>) -> i32 { + Self::sum(root, false) + } + + fn sum(node: Option>>, is_left: bool) -> i32 { + if node.is_none() { + return 0; + } + + let node = node.unwrap(); + if is_left && node.borrow().left.is_none() && node.borrow().right.is_none() { + return node.borrow().val; + } + + let left = Rc::clone(&node).borrow_mut().left.take(); + let right = Rc::clone(&node).borrow_mut().right.take(); + + Self::sum(left, true) + Self::sum(right, false) + } +} diff --git a/src/bin/sum-of-matrix-after-queries.rs b/src/bin/sum-of-matrix-after-queries.rs new file mode 100644 index 00000000..cf6c8655 --- /dev/null +++ b/src/bin/sum-of-matrix-after-queries.rs @@ -0,0 +1,38 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + /// 正难则反,倒序操作 + pub fn matrix_sum_queries(n: i32, queries: Vec>) -> i64 { + use std::collections::HashMap; + // r1行 r2列 + let (mut r1, mut r2) = (HashMap::new(), HashMap::new()); + let mut sum = 0; + for i in queries.into_iter().rev() { + match i[0] { + 0 => { + if r1.contains_key(&i[1]) { + continue; + } + + sum += (n as i64 - r2.len() as i64) * i[2] as i64; + r1.insert(i[1], ()); + } + 1 => { + if r2.contains_key(&i[1]) { + continue; + } + + sum += (n as i64 - r1.len() as i64) * i[2] as i64; + r2.insert(i[1], ()); + } + _ => unreachable!(), + } + } + + sum + } +} diff --git a/src/bin/sum-of-root-to-leaf-binary-numbers.rs b/src/bin/sum-of-root-to-leaf-binary-numbers.rs new file mode 100644 index 00000000..7db18689 --- /dev/null +++ b/src/bin/sum-of-root-to-leaf-binary-numbers.rs @@ -0,0 +1,52 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +use std::cell::RefCell; +use std::rc::Rc; + +// Definition for a binary tree node. +#[derive(Debug, PartialEq, Eq)] +pub struct TreeNode { + pub val: i32, + pub left: Option>>, + pub right: Option>>, +} + +impl TreeNode { + #[inline] + pub fn new(val: i32) -> Self { + TreeNode { + val, + left: None, + right: None, + } + } +} + +fn main() {} + +struct Solution; + +impl Solution { + pub fn sum_root_to_leaf(root: Option>>) -> i32 { + Self::f(root, 0) + } + + fn f(root: Option>>, i: i32) -> i32 { + if root.is_none() { + return 0; + } + + let root = root.unwrap(); + let left = root.borrow_mut().left.take(); + let right = root.borrow_mut().right.take(); + + let new_i = (i << 1) + root.borrow().val; + + match (left, right) { + (None, None) => new_i, + (Some(l), Some(y)) => Self::f(Some(l), new_i) + Self::f(Some(y), new_i), + (Some(l), None) => Self::f(Some(l), new_i), + (None, Some(y)) => Self::f(Some(y), new_i), + } + } +} diff --git a/src/bin/sum-of-squares-of-special-elements.rs b/src/bin/sum-of-squares-of-special-elements.rs new file mode 100644 index 00000000..b687fd38 --- /dev/null +++ b/src/bin/sum-of-squares-of-special-elements.rs @@ -0,0 +1,15 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn sum_of_squares(nums: Vec) -> i32 { + let n = nums.len(); + nums.into_iter() + .enumerate() + .filter_map(|(x, y)| if n % (x + 1) == 0 { Some(y * y) } else { None }) + .sum() + } +} diff --git a/src/bin/sum-of-two-integers.rs b/src/bin/sum-of-two-integers.rs new file mode 100644 index 00000000..3b46b038 --- /dev/null +++ b/src/bin/sum-of-two-integers.rs @@ -0,0 +1,34 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + assert_eq!(10, Solution::get_sum(4, 6)); + assert_eq!(10, Solution::get_sum(12, -2)); + assert_eq!(10, Solution::get_sum(0, 10)); + assert_eq!(10, Solution::get_sum(10, 0)); +} + +struct Solution; + +impl Solution { + // 反码:正数本身,负数非符号取反 + // 补码:正数本身,负数反码+1 + pub fn get_sum1(a: i32, b: i32) -> i32 { + if b == 0 { + return a; + } + + let (sum, carry) = (a ^ b, (a & b) << 1); + Self::get_sum(sum, carry) + } + + pub fn get_sum(a: i32, b: i32) -> i32 { + let mut sum = a; + let mut carry = b; + while carry != 0 { + let sum1 = sum ^ carry; + carry = (sum & carry) << 1; + sum = sum1; + } + sum + } +} diff --git a/src/bin/sum-of-values-at-indices-with-k-set-bits.rs b/src/bin/sum-of-values-at-indices-with-k-set-bits.rs new file mode 100644 index 00000000..94dc044f --- /dev/null +++ b/src/bin/sum-of-values-at-indices-with-k-set-bits.rs @@ -0,0 +1,20 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() { + assert_eq!( + Solution::sum_indices_with_k_set_bits(vec![5, 10, 1, 5, 2], 1), + 13 + ); +} + +struct Solution; + +impl Solution { + pub fn sum_indices_with_k_set_bits(nums: Vec, k: i32) -> i32 { + nums.into_iter() + .enumerate() + .filter(|(x, _)| x.count_ones() as i32 == k) + .map(|(_, x)| x) + .sum() + } +} diff --git a/src/bin/sum-root-to-leaf-numbers.rs b/src/bin/sum-root-to-leaf-numbers.rs new file mode 100644 index 00000000..38e25e21 --- /dev/null +++ b/src/bin/sum-root-to-leaf-numbers.rs @@ -0,0 +1,60 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +// Definition for a binary tree node. +#[derive(Debug, PartialEq, Eq)] +pub struct TreeNode { + pub val: i32, + pub left: Option>>, + pub right: Option>>, +} + +impl TreeNode { + #[inline] + pub fn new(val: i32) -> Self { + TreeNode { + val, + left: None, + right: None, + } + } +} + +use std::cell::RefCell; +use std::rc::Rc; + +impl Solution { + pub fn sum_numbers(root: Option>>) -> i32 { + if root.is_none() { + return 0; + } + let v = root.as_ref().unwrap().borrow().val; + let mut s = vec![(v, root)]; + let mut sum = 0; + + while !s.is_empty() { + let (x, r) = s.pop().unwrap(); + let left = r.as_ref().unwrap().borrow_mut().left.take(); + let right = r.as_ref().unwrap().borrow_mut().right.take(); + + if left.is_none() && right.is_none() { + sum += x; + } + + if left.is_some() { + let v = left.as_ref().unwrap().borrow().val; + s.push((x * 10 + v, left)); + } + + if right.is_some() { + let v = right.as_ref().unwrap().borrow().val; + s.push((x * 10 + v, right)); + } + } + + sum + } +} diff --git a/src/bin/summary-ranges.rs b/src/bin/summary-ranges.rs new file mode 100644 index 00000000..2beefec5 --- /dev/null +++ b/src/bin/summary-ranges.rs @@ -0,0 +1,37 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + println!("{:?}", Solution::summary_ranges(vec![0, 1, 2, 4, 5, 7])); +} + +struct Solution; + +impl Solution { + pub fn summary_ranges(nums: Vec) -> Vec { + if nums.len() == 0 { + return vec![]; + } + + let mut v = vec![]; + let (mut slow, mut fast) = (0usize, 0usize); + + while fast <= nums.len() { + if fast == 0 { + fast += 1; + continue; + } + + if fast == nums.len() || nums[fast] - nums[fast - 1] != 1 { + if fast - 1 == slow { + v.push(nums[fast - 1].to_string()); + } else { + v.push(format!("{}->{}", nums[slow], nums[fast - 1])); + } + slow = fast; + } + fast += 1; + } + + v + } +} diff --git a/src/bin/surface-area-of-3d-shapes.rs b/src/bin/surface-area-of-3d-shapes.rs new file mode 100644 index 00000000..a2f894eb --- /dev/null +++ b/src/bin/surface-area-of-3d-shapes.rs @@ -0,0 +1,53 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn surface_area(grid: Vec>) -> i32 { + let mut result = 0; + + for i in 0..grid.len() { + for j in 0..grid[0].len() { + if grid[i][j] != 0 { + result += 2; + } + + if i == 0 { + result += grid[i][j]; + } else { + if grid[i - 1][j] < grid[i][j] { + result += grid[i][j] - grid[i - 1][j]; + } + } + + if i == grid.len() - 1 { + result += grid[i][j]; + } else { + if grid[i + 1][j] < grid[i][j] { + result += grid[i][j] - grid[i + 1][j] + } + } + + if j == 0 { + result += grid[i][j]; + } else { + if grid[i][j - 1] < grid[i][j] { + result += grid[i][j] - grid[i][j - 1]; + } + } + + if j == grid[0].len() - 1 { + result += grid[i][j]; + } else { + if grid[i][j + 1] < grid[i][j] { + result += grid[i][j] - grid[i][j + 1]; + } + } + } + } + + result + } +} diff --git a/src/bin/swap-nodes-in-pairs.rs b/src/bin/swap-nodes-in-pairs.rs new file mode 100644 index 00000000..2de6ac0f --- /dev/null +++ b/src/bin/swap-nodes-in-pairs.rs @@ -0,0 +1,35 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +// Definition for singly-linked list. +#[derive(PartialEq, Eq, Clone, Debug)] +pub struct ListNode { + pub val: i32, + pub next: Option>, +} + +impl ListNode { + #[inline] + fn new(val: i32) -> Self { + ListNode { next: None, val } + } +} + +impl Solution { + pub fn swap_pairs(head: Option>) -> Option> { + match head { + Some(mut x) => match x.next.take() { + Some(mut y) => { + x.next = Self::swap_pairs(y.next.take()); + y.next = Some(x); + Some(y) + } + None => Some(x), + }, + None => None, + } + } +} diff --git a/src/bin/swapping-nodes-in-a-linked-list.rs b/src/bin/swapping-nodes-in-a-linked-list.rs new file mode 100644 index 00000000..db82ac31 --- /dev/null +++ b/src/bin/swapping-nodes-in-a-linked-list.rs @@ -0,0 +1,68 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +// Definition for singly-linked list. +#[derive(PartialEq, Eq, Clone, Debug)] +pub struct ListNode { + pub val: i32, + pub next: Option>, +} + +impl ListNode { + #[inline] + fn new(val: i32) -> Self { + ListNode { next: None, val } + } +} + +impl Solution { + /// 普通方法,先获取所有的值,然后再组装新的链表返回 + pub fn swap_nodes1(mut head: Option>, k: i32) -> Option> { + let mut v = vec![]; + + while let Some(i) = head.take() { + v.push(i.val); + head = i.next; + } + let n = v.len() - k as usize; + v.swap(k as usize - 1, n); + + let mut head = None; + for i in (0..v.len()).rev() { + let mut node = ListNode::new(v[i]); + if head.is_none() { + head = Some(Box::new(node)); + } else { + node.next = head.take(); + head = Some(Box::new(node)); + } + } + + head + } + + /// 快慢指针,先快指针到第k个值的时候,慢指针从第一个元素开始移动 + /// 快指针到达最后一个元素的时候,慢指针刚好在倒数第k个元素的位置 + pub fn swap_nodes(head: Option>, k: i32) -> Option> { + let mut index = 1; + let (mut fast, mut slow, mut k_node) = (head.as_ref(), head.as_ref(), None); + + while fast.is_some() { + if index == k { + k_node = fast; + } else if index > k { + slow = slow.unwrap().next.as_ref(); + } + fast = fast.unwrap().next.as_ref(); + index += 1; + } + + let _f = k_node.unwrap().val; + let _s = slow.unwrap().val; + + head + } +} diff --git a/src/bin/symmetric-tree.rs b/src/bin/symmetric-tree.rs new file mode 100644 index 00000000..69ac66b7 --- /dev/null +++ b/src/bin/symmetric-tree.rs @@ -0,0 +1,105 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + let root = Some(Rc::new(RefCell::new(TreeNode { + val: 1, + left: Some(Rc::new(RefCell::new(TreeNode { + val: 2, + left: Some(Rc::new(RefCell::new(TreeNode { + val: 3, + left: None, + right: None, + }))), + right: Some(Rc::new(RefCell::new(TreeNode { + val: 4, + left: None, + right: None, + }))), + }))), + right: Some(Rc::new(RefCell::new(TreeNode { + val: 2, + left: Some(Rc::new(RefCell::new(TreeNode { + val: 4, + left: None, + right: None, + }))), + right: Some(Rc::new(RefCell::new(TreeNode { + val: 3, + left: None, + right: None, + }))), + }))), + }))); + + assert!(Solution::is_symmetric(root)); +} + +struct Solution; + +// Definition for a binary tree node. +#[derive(Debug, PartialEq, Eq)] +pub struct TreeNode { + pub val: i32, + pub left: Option>>, + pub right: Option>>, +} + +impl TreeNode { + #[inline] + pub fn new(val: i32) -> Self { + TreeNode { + val, + left: None, + right: None, + } + } +} + +use std::cell::RefCell; +use std::rc::Rc; + +impl Solution { + pub fn is_symmetric(root: Option>>) -> bool { + if root.is_none() { + return true; + } + + let mut has_more = true; + let mut v = vec![]; + v.push(root.as_ref().unwrap().borrow_mut().left.take()); + v.push(root.as_ref().unwrap().borrow_mut().right.take()); + + while has_more { + has_more = false; + let (mut i, mut j) = (0, v.len() - 1); + let mut v1 = vec![None; v.len() * 2]; + while i < j { + match (v[i].as_ref(), v[j].as_ref()) { + (Some(x), Some(y)) => { + if x.borrow().val != y.borrow().val { + return false; + } + has_more = true; + + v1[i * 2] = x.borrow_mut().left.take(); + v1[i * 2 + 1] = x.borrow_mut().right.take(); + v1[j * 2] = y.borrow_mut().left.take(); + v1[j * 2 + 1] = y.borrow_mut().right.take(); + } + (None, None) => { + v1[i * 2] = None; + v1[i * 2 + 1] = None; + v1[j * 2] = None; + v1[j * 2 + 1] = None; + } + _ => return false, + } + i += 1; + j -= 1; + } + v = v1; + } + + true + } +} diff --git a/src/bin/take-gifts-from-the-richest-pile.rs b/src/bin/take-gifts-from-the-richest-pile.rs new file mode 100644 index 00000000..c79840c8 --- /dev/null +++ b/src/bin/take-gifts-from-the-richest-pile.rs @@ -0,0 +1,21 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn pick_gifts(gifts: Vec, k: i32) -> i64 { + let mut iter = gifts.into_iter().fuse(); + let mut sum = iter.clone().map(|x| x as i64).sum(); + let mut set = iter.collect::>(); + + for i in 0..k { + let m = set.pop().unwrap(); + sum -= m as i64 - (f64::sqrt(m as f64) as i64); + set.push(f64::sqrt(m as f64) as i32); + } + + sum + } +} diff --git a/src/bin/target-sum.rs b/src/bin/target-sum.rs new file mode 100644 index 00000000..ef2995ac --- /dev/null +++ b/src/bin/target-sum.rs @@ -0,0 +1,30 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +use std::vec; + +fn main() {} + +struct Solution; + +impl Solution { + pub fn find_target_sum_ways(nums: Vec, target: i32) -> i32 { + // Self::calc(&nums, target) + Self::calc(&nums, target) + } + + pub fn calc(nums: &[i32], target: i32) -> i32 { + if nums.is_empty() { + if target == 0 { + return 1; + } else { + return 0; + } + } + + if nums[0] == 0 { + Self::calc(&nums[1..], target - nums[0]) * 2 + } else { + Self::calc(&nums[1..], target - nums[0]) + Self::calc(&nums[1..], target + nums[0]) + } + } +} diff --git a/src/bin/task-scheduler.rs b/src/bin/task-scheduler.rs new file mode 100644 index 00000000..416a1702 --- /dev/null +++ b/src/bin/task-scheduler.rs @@ -0,0 +1,22 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn least_interval(tasks: Vec, n: i32) -> i32 { + let mut count = [0; 26]; + + for &v in tasks.iter() { + count[(v as u8 - b'A') as usize] += 1 + } + + let max = count.iter().map(|x| *x).max().unwrap(); + + let mut t = 0; + let t = count.iter().filter(|x| **x == max).count(); // 与max数量一致的任务数量 + + (tasks.len() as i32).max((n + 1) * (max - 1) + t as i32) + } +} diff --git a/src/bin/the-employee-that-worked-on-the-longest-task.rs b/src/bin/the-employee-that-worked-on-the-longest-task.rs new file mode 100644 index 00000000..2ddf58c9 --- /dev/null +++ b/src/bin/the-employee-that-worked-on-the-longest-task.rs @@ -0,0 +1,26 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn hardest_worker(n: i32, logs: Vec>) -> i32 { + let mut t = 0; + let mut r = 0; + + for i in 0..logs.len() { + if i == 0 { + t = logs[i][0]; + r = logs[i][1]; + } else if logs[i][1] - logs[i - 1][1] > r { + t = logs[i][0]; + r = logs[i][1] - logs[i - 1][1]; + } else if logs[i][1] - logs[i - 1][1] == r { + t = t.min(logs[i][0]); + } + } + + t + } +} diff --git a/src/bin/third-maximum-number.rs b/src/bin/third-maximum-number.rs new file mode 100644 index 00000000..df5c0a13 --- /dev/null +++ b/src/bin/third-maximum-number.rs @@ -0,0 +1,25 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn third_max(nums: Vec) -> i32 { + let (mut a, mut b, mut c) = (None, None, None); + for i in nums { + if a.is_none() || Some(i) > a { + c = b; + b = a; + a = Some(i); + } else if (b.is_none() || Some(i) > b) && Some(i) != a { + c = b; + b = Some(i); + } else if (c.is_none() || Some(i) > c) && Some(i) != b && Some(i) != a { + c = Some(i); + } + } + + c.unwrap_or(a.unwrap()) + } +} diff --git a/src/bin/thousand-separator.rs b/src/bin/thousand-separator.rs new file mode 100644 index 00000000..6a3aab04 --- /dev/null +++ b/src/bin/thousand-separator.rs @@ -0,0 +1,32 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn thousand_separator(n: i32) -> String { + let s = n.to_string(); + if n < 1000 { + return s; + } + let mut l = s.len() / 3; + if s.len() % 3 != 0 { + l += 1; + } + let mut v = vec![String::new(); l]; + let mut index = s.len(); + while index > 0 { + if index < 3 { + v[l - 1] = s[0..index].to_string(); + index = 0; + } else { + v[l - 1] = s[index - 3..index].to_string(); + index -= 3; + } + l -= 1; + } + + v.join(".") + } +} diff --git a/src/bin/three-consecutive-odds.rs b/src/bin/three-consecutive-odds.rs new file mode 100644 index 00000000..70204fb9 --- /dev/null +++ b/src/bin/three-consecutive-odds.rs @@ -0,0 +1,25 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn three_consecutive_odds(arr: Vec) -> bool { + let mut count = 0; + + for i in arr { + if i % 2 == 0 { + count = 0; + } else { + count += 1; + } + + if count >= 3 { + return true; + } + } + + false + } +} diff --git a/src/bin/throne-inheritance.rs b/src/bin/throne-inheritance.rs new file mode 100644 index 00000000..297cb5e3 --- /dev/null +++ b/src/bin/throne-inheritance.rs @@ -0,0 +1,68 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +/** + * `&self` means the method takes an immutable reference. + * If you need a mutable reference, change it to `&mut self` instead. + */ + +struct ThroneInheritance { + death: std::collections::HashSet, + tree: std::collections::HashMap>, + king_name: String, +} + +impl ThroneInheritance { + + fn new(kingName: String) -> Self { + Self { + death: std::collections::HashSet::new(), + tree: { + let mut tree = std::collections::HashMap::new(); + tree.insert(kingName.clone(), vec![]); + tree + }, + king_name: kingName, + } + } + + fn birth(&mut self, parent_name: String, child_name: String) { + self.tree.entry(parent_name).and_modify(|x|x.push(child_name.clone())); + self.tree.entry(child_name.clone()).or_insert(vec![]); + } + + fn death(&mut self, name: String) { + self.death.insert(name); + } + + fn dfs(&self, name: &String, data: &mut Vec) { + if !self.death.contains(name) { + data.push(name.clone()); + } + + if let Some(children) = self.tree.get(name) { + for child in children { + self.dfs(child, data); + } + } + } + + fn get_inheritance_order(&self) -> Vec { + let mut data = vec![]; + + self.dfs(&self.king_name, &mut data); + + data + } +} + +/** + * Your ThroneInheritance object will be instantiated and called as such: + * let obj = ThroneInheritance::new(kingName); + * obj.birth(parentName, childName); + * obj.death(name); + * let ret_3: Vec = obj.get_inheritance_order(); + */ diff --git a/src/bin/ti-huan-kong-ge-lcof.rs b/src/bin/ti-huan-kong-ge-lcof.rs new file mode 100644 index 00000000..97b23ed4 --- /dev/null +++ b/src/bin/ti-huan-kong-ge-lcof.rs @@ -0,0 +1,20 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn replace_space(s: String) -> String { + let mut result = String::new(); + for i in s.chars() { + if i == ' ' { + result.push_str("%20"); + } else { + result.push(i); + } + } + + result + } +} diff --git a/src/bin/time-needed-to-buy-tickets.rs b/src/bin/time-needed-to-buy-tickets.rs new file mode 100644 index 00000000..2041af7d --- /dev/null +++ b/src/bin/time-needed-to-buy-tickets.rs @@ -0,0 +1,27 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn time_required_to_buy(tickets: Vec, k: i32) -> i32 { + let n = tickets[k as usize]; + + tickets + .into_iter() + .enumerate() + .map(|(i, v)| { + if i <= k as usize { + v.min(n) + } else { + if v < n { + v + } else { + n - 1 + } + } + }) + .sum() + } +} diff --git a/src/bin/to-lower-case.rs b/src/bin/to-lower-case.rs new file mode 100644 index 00000000..2bd45040 --- /dev/null +++ b/src/bin/to-lower-case.rs @@ -0,0 +1,21 @@ +#![allow(dead_code, unused, unused_variables)] + +use serde::de::Unexpected::Str; + +fn main() {} + +struct Solution; + +impl Solution { + pub fn to_lower_case(s: String) -> String { + let mut new = Vec::with_capacity(s.len()); + s.bytes().into_iter().for_each(|mut x| { + if x >= b'A' && x <= b'Z' { + x += 32; + } + new.push(x); + }); + + String::from_utf8(new).unwrap() + } +} diff --git a/src/bin/top-k-frequent-elements.rs b/src/bin/top-k-frequent-elements.rs new file mode 100644 index 00000000..ce7c92fa --- /dev/null +++ b/src/bin/top-k-frequent-elements.rs @@ -0,0 +1,84 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +use std::vec; + +fn main() { + assert_eq!( + Solution::top_k_frequent(vec![1, 1, 1, 2, 2, 3], 2), + vec![2, 1] + ); + + assert_eq!(Solution::top_k_frequent(vec![1], 1), vec![1]); + assert_eq!(Solution::top_k_frequent(vec![3, 0, 1, 0], 1), vec![0]); +} + +struct Solution; + +impl Solution { + /// 先获取数字对应的次数,再用小顶堆,再遍历堆 + pub fn top_k_frequent(nums: Vec, k: i32) -> Vec { + let mut hash = std::collections::HashMap::new(); + + for i in nums { + hash.entry(i).and_modify(|x| *x += 1).or_insert(1); + } + + let mut heap = vec![]; + + for (x, y) in hash { + Self::buildHeap(&mut heap, k as usize, (x, y)); + } + + heap.into_iter().map(|x| x.0).collect() + } + + fn buildHeap(heap: &mut Vec<(i32, i32)>, length: usize, elem: (i32, i32)) { + if heap.len() == length { + if heap[0].1 < elem.1 { + // 先删除掉第一个元素 + heap.swap(0, length - 1); + heap.remove(length - 1); + let mut start = 0; + // 堆顶向下比较 + while start < length { + if start * 2 + 1 < heap.len() && start * 2 + 2 < heap.len() { + let mut min = start * 2 + 1; + if heap[start * 2 + 1].1 > heap[start * 2 + 2].1 { + min = start * 2 + 2; + } + + if heap[min].1 < heap[start].1 { + heap.swap(start, min); + start = min; + } else { + break; + } + } else if start * 2 + 1 < heap.len() { + if heap[start * 2 + 1].1 < heap[start].1 { + heap.swap(start, start * 2 + 1); + start = start * 2 + 1; + } else { + break; + } + } else { + break; + } + } + } else { + return; + } + } + + heap.push(elem); + let mut start = heap.len() - 1; + + while start > 0 { + if heap[(start - 1) / 2].1 > heap[start].1 { + heap.swap(start, (start - 1) / 2); + start = (start - 1) / 2; + } else { + return; + } + } + } +} diff --git a/src/bin/total-distance-traveled.rs b/src/bin/total-distance-traveled.rs new file mode 100644 index 00000000..1d964065 --- /dev/null +++ b/src/bin/total-distance-traveled.rs @@ -0,0 +1,28 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn distance_traveled(main_tank: i32, additional_tank: i32) -> i32 { + let (mut main_tank, mut additional_tank) = (main_tank, additional_tank); + let mut result = 0; + + while main_tank > 0 { + if main_tank >= 5 { + main_tank -= 5; + result += 50; + if additional_tank > 0 { + main_tank += 1; + additional_tank -= 1; + } + } else { + result += main_tank * 10; + main_tank = 0; + } + } + + result + } +} diff --git a/src/bin/trapping-rain-water.rs b/src/bin/trapping-rain-water.rs new file mode 100644 index 00000000..f1fdf672 --- /dev/null +++ b/src/bin/trapping-rain-water.rs @@ -0,0 +1,69 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() { + assert_eq!(Solution::trap(vec![0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1]), 6); + assert_eq!( + Solution::trap_stack(vec![0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1]), + 6 + ); +} + +struct Solution; + +impl Solution { + pub fn trap(height: Vec) -> i32 { + let mut max_left = vec![0; height.len()]; // 左边的最大值 + + for (i, &v) in height.iter().enumerate() { + if i == 0 { + max_left[i] = v; + } else { + max_left[i] = v.max(max_left[i - 1]); + } + } + + let mut max_right = vec![0; height.len()]; + + for (i, &v) in height.iter().rev().enumerate() { + let index = max_right.len() - i - 1; + if i == 0 { + max_right[index] = v; + } else { + max_right[index] = v.max(max_right[index + 1]); + } + } + + let mut ans = 0; + + for (i, &v) in height.iter().enumerate() { + let min = max_left[i].min(max_right[i]); + if v < min { + ans += min - v; + } + } + + ans + } + + pub fn trap_stack(height: Vec) -> i32 { + let mut ans = 0; + let mut stack = vec![]; + + for i in 0..height.len() { + while !stack.is_empty() && height[stack[stack.len() - 1]] < height[i] { + let top = stack.pop().unwrap(); + if stack.is_empty() { + break; + } + + let &l = stack.last().unwrap(); + let h = height[i].min(height[l]) - height[top]; + ans += (i as i32 - l as i32 - 1) * h; + } + + stack.push(i); + } + + ans + } +} diff --git a/src/bin/triangle.rs b/src/bin/triangle.rs new file mode 100644 index 00000000..2a172726 --- /dev/null +++ b/src/bin/triangle.rs @@ -0,0 +1,35 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn minimum_total(triangle: Vec>) -> i32 { + let mut x = vec![vec![]; triangle.len()]; + Self::f(&triangle, &mut x, 0, 0); + x[0][0] + } + + /// index1: 二维数组的下标 + /// index2: 行的下标 + fn f(v: &Vec>, x: &mut Vec>, index1: usize, index2: usize) { + if v.len() - 1 == index1 { + x[index1] = v[index1].clone(); + return; + } + + if index2 == 0 { + x[index1] = vec![-1; v[index1].len()]; + } + + if x[index1][index2] != -1 { + return; + } + + Self::f(v, x, index1 + 1, index2); + Self::f(v, x, index1 + 1, index2 + 1); + + x[index1][index2] = v[index1][index2] + x[index1 + 1][index2].min(x[index1 + 1][index2 + 1]) + } +} diff --git a/src/bin/tuple-with-same-product.rs b/src/bin/tuple-with-same-product.rs new file mode 100644 index 00000000..39a585ec --- /dev/null +++ b/src/bin/tuple-with-same-product.rs @@ -0,0 +1,25 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn tuple_same_product(nums: Vec) -> i32 { + let mut s = std::collections::HashMap::new(); + let mut r = 0; + for i in 0..nums.len() { + for j in i + 1..nums.len() { + if let Some(x) = s.get_mut(&(nums[i] * nums[j])) { + r += (*x * 8); + *x += 1; + continue; + } + + s.insert(nums[i] * nums[j], 1); + } + } + + r + } +} diff --git a/src/bin/tvdfij.rs b/src/bin/tvdfij.rs new file mode 100644 index 00000000..1e00f884 --- /dev/null +++ b/src/bin/tvdfij.rs @@ -0,0 +1,26 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() { + assert_eq!(Solution::pivot_index(vec![1, 2, 3]), -1); + assert_eq!(Solution::pivot_index(vec![2, 1, -1]), 0); + assert_eq!(Solution::pivot_index(vec![1, 7, 3, 6, 5, 6]), 3); +} + +struct Solution; + +impl Solution { + pub fn pivot_index(nums: Vec) -> i32 { + let sum: i32 = nums.iter().map(|x| *x).sum(); + + let mut left = 0; + for i in 0..nums.len() { + if left == sum - left - nums[i] { + return i as i32; + } + + left += nums[i]; + } + + -1 + } +} diff --git a/src/bin/two-out-of-three.rs b/src/bin/two-out-of-three.rs new file mode 100644 index 00000000..4d806c96 --- /dev/null +++ b/src/bin/two-out-of-three.rs @@ -0,0 +1,37 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +use std::collections::HashSet; + +fn main() {} + +struct Solution; + +impl Solution { + pub fn two_out_of_three(nums1: Vec, nums2: Vec, nums3: Vec) -> Vec { + use std::collections::HashSet; + let mut hash1: HashSet<_> = nums1.iter().collect(); + let mut hash2 = HashSet::new(); + let mut hash3 = HashSet::new(); + + let mut result = vec![]; + + for i in nums2.iter() { + if hash1.contains(i) && !hash2.contains(i) { + result.push(*i); + } + hash2.insert(*i); + } + + for i in nums3.iter() { + if ((hash1.contains(i) && !hash2.contains(i)) + || (!hash1.contains(i) && hash2.contains(i))) + && !hash3.contains(i) + { + result.push(*i); + } + hash3.insert(*i); + } + + result + } +} diff --git a/src/bin/two-sum-ii-input-array-is-sorted.rs b/src/bin/two-sum-ii-input-array-is-sorted.rs new file mode 100644 index 00000000..bd3bb0ad --- /dev/null +++ b/src/bin/two-sum-ii-input-array-is-sorted.rs @@ -0,0 +1,22 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn two_sum(numbers: Vec, target: i32) -> Vec { + let (mut start, mut end) = (1, numbers.len()); + + while start < end { + let sum = numbers[start - 1] + numbers[end - 1]; + match target.cmp(&sum) { + std::cmp::Ordering::Equal => break, + std::cmp::Ordering::Less => end -= 1, + std::cmp::Ordering::Greater => start += 1, + } + } + + vec![start as i32, end as i32] + } +} diff --git a/src/bin/two-sum-iv-input-is-a-bst.rs b/src/bin/two-sum-iv-input-is-a-bst.rs new file mode 100644 index 00000000..edbfb3d6 --- /dev/null +++ b/src/bin/two-sum-iv-input-is-a-bst.rs @@ -0,0 +1,69 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +// Definition for a binary tree node. +#[derive(Debug, PartialEq, Eq)] +pub struct TreeNode { + pub val: i32, + pub left: Option>>, + pub right: Option>>, +} + +impl TreeNode { + #[inline] + pub fn new(val: i32) -> Self { + TreeNode { + val, + left: None, + right: None, + } + } +} + +use std::cell::RefCell; +use std::rc::Rc; + +impl Solution { + /// 遍历二叉树 + /// 遍历的时候判断hash表中是否有k-node的值 + /// 存在则返回true + /// 不存在就把当前node的值放入hash表中 + pub fn find_target(root: Option>>, k: i32) -> bool { + let mut hash = std::collections::HashMap::::new(); + return Solution::scan_tree(root, &mut hash, k); + } + + fn scan_tree( + root: Option>>, + hash: &mut std::collections::HashMap, + k: i32, + ) -> bool { + if root.is_none() { + return false; + } + + let v = root.as_ref().unwrap().borrow().val; + if hash.get(&(k - v)).is_some() { + return true; + } + + hash.insert(v, ()); + + let root = root.unwrap(); + + let left = Solution::scan_tree(root.borrow_mut().left.take(), hash, k); + if left { + return left; + } + + let right = Solution::scan_tree(root.borrow_mut().right.take(), hash, k); + if right { + return right; + } + + false + } +} diff --git a/src/bin/two-sum.rs b/src/bin/two-sum.rs new file mode 100644 index 00000000..0ad05dbe --- /dev/null +++ b/src/bin/two-sum.rs @@ -0,0 +1,21 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn two_sum(nums: Vec, target: i32) -> Vec { + let mut hash = std::collections::HashMap::new(); + let mut result = Vec::with_capacity(2); + for (index, value) in nums.into_iter().enumerate() { + if let Some(&i) = hash.get(&(target - value)) { + result.push(i as i32); + result.push(index as i32); + } else { + hash.insert(value, index); + } + } + result + } +} diff --git a/src/bin/type-of-triangle-ii.rs b/src/bin/type-of-triangle-ii.rs new file mode 100644 index 00000000..f96fc2ba --- /dev/null +++ b/src/bin/type-of-triangle-ii.rs @@ -0,0 +1,24 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn triangle_type(nums: Vec) -> String { + let mut nums = nums; + nums.sort_unstable(); + + if nums[0] + nums[1] <= nums[2] { + return "none".into(); + } + + if nums[0] == nums[1] && nums[1] == nums[2] { + "equilateral".into() + } else if nums[0] == nums[1] || nums[1] == nums[2] { + "isosceles".into() + } else { + "scalene".into() + } + } +} diff --git a/src/bin/uOAnQW.rs b/src/bin/uOAnQW.rs new file mode 100644 index 00000000..8ae60618 --- /dev/null +++ b/src/bin/uOAnQW.rs @@ -0,0 +1,44 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn maxmium_score(cards: Vec, cnt: i32) -> i32 { + let mut cards = cards; + cards.sort_unstable_by(|x, y| x.cmp(y).reverse()); + + let (mut min_even, mut min_odd) = (None::, None::); + let (mut max_even, mut max_odd) = (None::, None::); + let mut sum = 0; + + for &i in cards[0..cnt as usize].iter() { + sum += i; + if i % 2 == 0 { + min_even = min_even.map_or(Some(i), |x| Some(x.min(i))); + } else { + min_odd = min_odd.map_or(Some(i), |x| Some(x.min(i))); + } + } + + if sum % 2 == 0 { + return sum; + } + + for &i in cards[cnt as usize..].iter() { + if i % 2 == 0 { + max_even = max_even.map_or(Some(i), |x| Some(x.max(i))); + } else { + max_odd = max_odd.map_or(Some(i), |x| Some(x.max(i))); + } + } + + match (min_even, max_odd, min_odd, max_even) { + (Some(x1), Some(y1), Some(x2), Some(y2)) => (sum - x1 + y1).max(sum - x2 + y2), + (Some(x1), Some(y1), _, _) => sum - x1 + y1, + (_, _, Some(x2), Some(y2)) => sum - x2 + y2, + _ => 0, + } + } +} diff --git a/src/bin/ugly-number.rs b/src/bin/ugly-number.rs new file mode 100644 index 00000000..d711d81a --- /dev/null +++ b/src/bin/ugly-number.rs @@ -0,0 +1,55 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn is_ugly(num: i32) -> bool { + if num == 1 { + return true; + } + + if num == 0 { + return false; + } + + let mut num = num; + + while num != 1 { + if num % 2 == 0 { + num /= 2; + } else if num % 3 == 0 { + num /= 3; + } else if num % 5 == 0 { + num /= 5; + } else { + return false; + } + } + + true + } + + pub fn is_ugly1(num: i32) -> bool { + if num == 0 { + return false; + } + + let mut num = num; + + while num % 5 == 0 { + num /= 5; + } + + while num % 3 == 0 { + num /= 3; + } + + while num % 2 == 0 { + num /= 2; + } + + num == 1 + } +} diff --git a/src/bin/unique-binary-search-trees-ii.rs b/src/bin/unique-binary-search-trees-ii.rs new file mode 100644 index 00000000..bf84a90a --- /dev/null +++ b/src/bin/unique-binary-search-trees-ii.rs @@ -0,0 +1,59 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + println!("{:?}", Solution::generate_trees(3)) +} + +struct Solution; + +// Definition for a binary tree node. +#[derive(Debug, PartialEq, Eq)] +pub struct TreeNode { + pub val: i32, + pub left: Option>>, + pub right: Option>>, +} + +impl TreeNode { + #[inline] + pub fn new(val: i32) -> Self { + TreeNode { + val, + left: None, + right: None, + } + } +} + +use std::cell::RefCell; +use std::rc::Rc; + +impl Solution { + pub fn generate_trees(n: i32) -> Vec>>> { + Self::f(1, n) + } + + fn f(start: i32, end: i32) -> Vec>>> { + if start > end { + return vec![None]; + } + + let mut result = vec![]; + + for i in start..=end { + let left = Self::f(start, i - 1); + let right = Self::f(i + 1, end); + + for j in &left { + for k in &right { + let mut node = TreeNode::new(i); + node.left = j.clone(); + node.right = k.clone(); + result.push(Some(Rc::new(RefCell::new(node)))); + } + } + } + + result + } +} diff --git a/src/bin/unique-binary-search-trees.rs b/src/bin/unique-binary-search-trees.rs new file mode 100644 index 00000000..68da01a3 --- /dev/null +++ b/src/bin/unique-binary-search-trees.rs @@ -0,0 +1,25 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + println!("{}", Solution::num_trees(3)); + println!("{}", Solution::num_trees(4)); + println!("{}", Solution::num_trees(19)); +} + +struct Solution; + +impl Solution { + pub fn num_trees(n: i32) -> i32 { + let mut v = vec![0; n as usize + 1]; + v[0] = 1; + v[1] = 1; + + for i in 2..=n as usize { + for j in 1..=i { + v[i] += v[j - 1] * v[i - j]; + } + } + + v[n as usize] + } +} diff --git a/src/bin/unique-number-of-occurrences.rs b/src/bin/unique-number-of-occurrences.rs new file mode 100644 index 00000000..5f1c107b --- /dev/null +++ b/src/bin/unique-number-of-occurrences.rs @@ -0,0 +1,27 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn unique_occurrences(arr: Vec) -> bool { + let mut s: std::collections::HashMap = Default::default(); + + for i in arr { + s.entry(i).and_modify(|x| *x += 1).or_insert(1); + } + + let mut s1 = std::collections::HashSet::new(); + + for (_, v) in s.into_iter() { + if s1.contains(&v) { + return false; + } + + s1.insert(v); + } + + true + } +} diff --git a/src/bin/unique-paths-ii.rs b/src/bin/unique-paths-ii.rs new file mode 100644 index 00000000..96fef023 --- /dev/null +++ b/src/bin/unique-paths-ii.rs @@ -0,0 +1,54 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn unique_paths_with_obstacles(obstacle_grid: Vec>) -> i32 { + let mut r = vec![vec![0; obstacle_grid[0].len()]; obstacle_grid.len()]; + Self::scan(&mut r, &obstacle_grid, 0, 0); + if r[0][0] != -1 { + r[0][0] + } else { + 0 + } + } + + fn scan(v: &mut Vec>, ob: &Vec>, index1: usize, index2: usize) { + let (s1, s2) = (v.len() - 1, v[0].len() - 1); + if index1 == s1 && index2 == s2 && ob[index1][index2] != 1 { + v[index1][index2] = 1; + return; + } + + if index1 > s1 || index2 > s2 || v[index1][index2] != 0 { + return; + } + + // 当存在障碍物时 + if ob[index1][index2] == 1 { + v[index1][index2] = -1; + return; + } + + Self::scan(v, ob, index1 + 1, index2); + Self::scan(v, ob, index1, index2 + 1); + + if index1 < s1 { + v[index1][index2] += if v[index1 + 1][index2] != -1 { + v[index1 + 1][index2] + } else { + 0 + }; + } + + if index2 < s2 { + v[index1][index2] += if v[index1][index2 + 1] != -1 { + v[index1][index2 + 1] + } else { + 0 + }; + } + } +} diff --git a/src/bin/unique-paths.rs b/src/bin/unique-paths.rs new file mode 100644 index 00000000..84d31ff1 --- /dev/null +++ b/src/bin/unique-paths.rs @@ -0,0 +1,53 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + assert_eq!(28, Solution::unique_paths(3, 7)); +} + +struct Solution; + +impl Solution { + pub fn unique_paths(m: i32, n: i32) -> i32 { + let mut v = vec![vec![0; n as usize]; m as usize]; + + Self::calc(&mut v, 0, 0); + + v[0][0] + } + + fn calc(array: &mut Vec>, m: usize, n: usize) { + let s1 = array.len() - 1; + let s2 = array[0].len() - 1; + + if m == s1 && n == s2 { + array[s1][s2] = 1; + return; + } + + if array[m][n] != 0 { + return; + } + + if m == s1 { + if array[m][n + 1] == 0 { + Self::calc(array, m, n + 1); + } + array[m][n] = array[m][n + 1]; + } else if n == s2 { + if array[m + 1][n] == 0 { + Self::calc(array, m + 1, n); + } + array[m][n] = array[m + 1][n]; + } else { + if array[m + 1][n] == 0 { + Self::calc(array, m + 1, n); + } + + if array[m][n + 1] == 0 { + Self::calc(array, m, n + 1); + } + + array[m][n] = array[m + 1][n] + array[m][n + 1]; + } + } +} diff --git a/src/bin/univalued-binary-tree.rs b/src/bin/univalued-binary-tree.rs index 9e2b04c3..e7a78382 100644 --- a/src/bin/univalued-binary-tree.rs +++ b/src/bin/univalued-binary-tree.rs @@ -1,3 +1,5 @@ +#![allow(dead_code, unused, unused_variables)] + // Definition for a binary tree node. #[derive(Debug, PartialEq, Eq)] pub struct TreeNode { @@ -17,8 +19,8 @@ impl TreeNode { } } -use std::rc::Rc; use std::cell::RefCell; +use std::rc::Rc; struct Solution; diff --git a/src/bin/utf-8-validation.rs b/src/bin/utf-8-validation.rs new file mode 100644 index 00000000..1c534d62 --- /dev/null +++ b/src/bin/utf-8-validation.rs @@ -0,0 +1,48 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + assert!(Solution::valid_utf8(vec![197, 130, 1])); + assert!(!Solution::valid_utf8(vec![235, 140, 4])); + assert!(Solution::valid_utf8(vec![197, 130, 1])); + assert!(!Solution::valid_utf8(vec![248, 130, 130, 130])); +} + +struct Solution; + +impl Solution { + pub fn valid_utf8(data: Vec) -> bool { + let mut index = 0; + while index < data.len() { + let n = if data[index] & 248 == 240 { + 4 + } else if data[index] & 240 == 224 { + 3 + } else if data[index] & 224 == 192 { + 2 + } else if data[index] & 128 == 0 { + 1 + } else { + return false; + }; + + if index + n > data.len() || !Self::check(&data[index..index + n]) { + return false; + } + + index += n; + } + + index == data.len() + } + + /// 检查除第一位的后几位是否都是10开头的 + fn check(data: &[i32]) -> bool { + for &i in data.iter().skip(1) { + if i & 0b11000000 != 0b10000000 { + return false; + } + } + + true + } +} diff --git a/src/bin/valid-anagram.rs b/src/bin/valid-anagram.rs new file mode 100644 index 00000000..c497d481 --- /dev/null +++ b/src/bin/valid-anagram.rs @@ -0,0 +1,27 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn is_anagram(s: String, t: String) -> bool { + if s.len() != t.len() { + return false; + } + + let mut v = [0; 26]; + for &i in s.as_bytes().iter() { + v[(i - b'a') as usize] += 1; + } + + for &i in t.as_bytes().iter() { + v[(i - b'a') as usize] -= 1; + if v[(i - b'a') as usize] < 0 { + return false; + } + } + + true + } +} diff --git a/src/bin/valid-palindrome.rs b/src/bin/valid-palindrome.rs new file mode 100644 index 00000000..91a93535 --- /dev/null +++ b/src/bin/valid-palindrome.rs @@ -0,0 +1,39 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + assert_eq!(true, Solution::is_palindrome("A aa".to_string())); +} + +struct Solution; + +impl Solution { + pub fn is_palindrome(s: String) -> bool { + if s.is_empty() { + return true; + } + + let (mut start, mut end) = (0, s.len() - 1); + let s = s.as_bytes(); + + while start < end { + if !s[start].is_ascii_alphanumeric() { + start += 1; + continue; + } + + if !s[end].is_ascii_alphanumeric() { + end -= 1; + continue; + } + + if s[start].to_ascii_lowercase() == s[end].to_ascii_lowercase() { + start += 1; + end -= 1; + } else { + return false; + } + } + + true + } +} diff --git a/src/bin/valid-parentheses.rs b/src/bin/valid-parentheses.rs new file mode 100644 index 00000000..98d4c1a0 --- /dev/null +++ b/src/bin/valid-parentheses.rs @@ -0,0 +1,31 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn is_valid(s: String) -> bool { + let mut stack = vec![]; + + for i in s.chars() { + match i { + '(' | '{' | '[' => stack.push(i), + _ => { + if let Some(x) = stack.pop() { + if (x == '(' && i != ')') + || (x == '{' && i != '}') + || (x == '[' && i != ']') + { + return false; + } + } else { + return false; + } + } + } + } + + stack.is_empty() + } +} diff --git a/src/bin/valid-perfect-square.rs b/src/bin/valid-perfect-square.rs index 375c8000..7291ee5d 100644 --- a/src/bin/valid-perfect-square.rs +++ b/src/bin/valid-perfect-square.rs @@ -1,3 +1,5 @@ +#![allow(dead_code, unused, unused_variables)] + fn main() { assert_eq!(true, Solution::is_perfect_square(4), "4"); assert_eq!(false, Solution::is_perfect_square(5), "5"); @@ -8,7 +10,6 @@ fn main() { assert_eq!(true, Solution::is_perfect_square1(49000000), "49000000"); } - struct Solution; impl Solution { @@ -27,11 +28,7 @@ impl Solution { loop { if num / num1 == num1 { - return if num % num1 == 0 { - true - } else { - false - }; + return if num % num1 == 0 { true } else { false }; } else if num / num1 > num1 { last_num = num1; num1 *= 2; @@ -53,7 +50,7 @@ impl Solution { let mut start = 1; let mut sum = num; loop { - if sum == 0 { + if sum == 0 { return true; } else if sum < 0 { return false; diff --git a/src/bin/valid-sudoku.rs b/src/bin/valid-sudoku.rs new file mode 100644 index 00000000..6726005e --- /dev/null +++ b/src/bin/valid-sudoku.rs @@ -0,0 +1,41 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn is_valid_sudoku(board: Vec>) -> bool { + let mut row = [[0; 10]; 9]; + let mut column = [[0; 10]; 9]; + let mut boxes = [[[0; 10]; 3]; 3]; + + for i in 0..9 { + for j in 0..9 { + if board[i][j] == '.' { + continue; + } + let x: usize = board[i][j].to_string().parse().unwrap(); + if row[i][x] != 0 { + return false; + } else { + row[i][x] = 1; + } + + if column[j][x] != 0 { + return false; + } else { + column[j][x] = 1; + } + + if boxes[i / 3][j / 3][x] != 0 { + return false; + } else { + boxes[i / 3][j / 3][x] = 1; + } + } + } + + true + } +} diff --git a/src/bin/validate-binary-search-tree.rs b/src/bin/validate-binary-search-tree.rs new file mode 100644 index 00000000..de5d0934 --- /dev/null +++ b/src/bin/validate-binary-search-tree.rs @@ -0,0 +1,65 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +// Definition for a binary tree node. +#[derive(Debug, PartialEq, Eq)] +pub struct TreeNode { + pub val: i32, + pub left: Option>>, + pub right: Option>>, +} + +impl TreeNode { + #[inline] + pub fn new(val: i32) -> Self { + TreeNode { + val, + left: None, + right: None, + } + } +} + +use std::cell::RefCell; +use std::rc::Rc; + +impl Solution { + /// 中序遍历,遍历值都是递增的,当当前值小于或者等于前一个值,说明不是搜索二叉树 + pub fn is_valid_bst(root: Option>>) -> bool { + // 获取最小的值的节点,也就是最左节点 + let mut v = None; + Self::scan(root, &mut v) + } + + fn scan(root: Option>>, v: &mut Option) -> bool { + if root.is_none() { + return true; + } + let value = root.as_ref().unwrap().borrow().val; + let left = root.as_ref().unwrap().borrow_mut().left.take(); + let right = root.as_ref().unwrap().borrow_mut().right.take(); + + if left.is_some() { + if !Self::scan(left, v) { + return false; + } + } + + if v.is_some() && value <= v.unwrap() { + return false; + } + + *v = Some(value); + + if right.is_some() { + if !Self::scan(right, v) { + return false; + } + } + + true + } +} diff --git a/src/bin/validate-stack-sequences.rs b/src/bin/validate-stack-sequences.rs new file mode 100644 index 00000000..fcea6b5b --- /dev/null +++ b/src/bin/validate-stack-sequences.rs @@ -0,0 +1,50 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn validate_stack_sequences1(pushed: Vec, popped: Vec) -> bool { + let (mut index1, mut index2) = (0, 0); + let mut stack = vec![]; + + while index1 < pushed.len() || index2 < pushed.len() { + if index1 < pushed.len() + && (stack.is_empty() || *stack.last().unwrap() != popped[index2]) + { + stack.push(pushed[index1]); + index1 += 1; + } else { + match stack.pop() { + Some(x) if x == popped[index2] => { + index2 += 1; + } + _ => return false, + } + } + } + + stack.is_empty() + } + + pub fn validate_stack_sequences(pushed: Vec, popped: Vec) -> bool { + let mut index = 0; + let mut stack = vec![]; + + for i in pushed { + stack.push(i); + + while let Some(&x) = stack.last() { + if x == popped[index] { + stack.pop(); + index += 1; + } else { + break; + } + } + } + + stack.is_empty() + } +} diff --git a/src/bin/verify-preorder-serialization-of-a-binary-tree.rs b/src/bin/verify-preorder-serialization-of-a-binary-tree.rs new file mode 100644 index 00000000..1ab84076 --- /dev/null +++ b/src/bin/verify-preorder-serialization-of-a-binary-tree.rs @@ -0,0 +1,52 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + /// 栈 + /// 当栈顶出现两个#,则说明当前节点叶子节点,可以把叶子节点去掉(转化为一个#继续遍历) + pub fn is_valid_serialization1(preorder: String) -> bool { + let mut stack = vec![]; + for i in preorder.split(',') { + match i { + "#" => { + stack.push("#"); + while stack.len() >= 3 + && stack[stack.len() - 1] == "#" + && stack[stack.len() - 2] == "#" + && stack[stack.len() - 3] != "#" + { + stack.pop(); + stack.pop(); + stack.pop(); + stack.push("#"); + } + } + i => stack.push(i), + } + } + + stack.len() == 1 && stack[0] == "#" + } + + /// 入度出度。入度为多少节点指向它,出度是指它指向多少节点 + /// 入度+1,出度-1,最终和为0 则表示有效 + /// 注:整个过程中和必须大于等于0 + pub fn is_valid_serialization(preorder: String) -> bool { + let mut diff = 1; + for i in preorder.split(',') { + diff -= 1; + if diff < 0 { + return false; + } + + if i != "#" { + diff += 2; + } + } + + diff == 0 + } +} diff --git a/src/bin/visit-array-positions-to-maximize-score.rs b/src/bin/visit-array-positions-to-maximize-score.rs new file mode 100644 index 00000000..bf4f2c2b --- /dev/null +++ b/src/bin/visit-array-positions-to-maximize-score.rs @@ -0,0 +1,52 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() { + assert_eq!(Solution::max_score(vec![2, 3, 6, 1, 9, 2], 5), 13); + assert_eq!(Solution::max_score(vec![2, 4, 6, 8], 3), 20); + assert_eq!( + Solution::max_score( + vec![ + 18, 13, 60, 61, 57, 21, 10, 98, 51, 3, 13, 36, 72, 70, 68, 62, 52, 83, 63, 63, 53, + 42, 59, 98, 95, 48, 22, 64, 94, 80, 14, 14 + ], + 2 + ), + 1633 + ); + assert_eq!( + Solution::max_score( + vec![ + 38, 92, 23, 30, 25, 96, 6, 71, 78, 77, 33, 23, 71, 48, 87, 77, 53, 28, 6, 20, 90, + 83, 42, 21, 64, 95, 84, 29, 22, 21, 33, 36, 53, 51, 85, 25, 80, 56, 71, 69, 5, 21, + 4, 84, 28, 16, 65, 7 + ], + 52 + ), + 1545 + ); +} + +struct Solution; + +impl Solution { + pub fn max_score(nums: Vec, x: i32) -> i64 { + let (mut a, mut b) = (i64::MIN, i64::MIN); // a为奇最大值,b为偶最大值 + if nums[0] % 2 == 0 { + b = nums[0] as i64; + } else { + a = nums[0] as i64; + } + + let x = x as i64; + for &i in nums[1..].iter() { + let i = i as i64; + if i % 2 == 0 { + b = (b + i).max(if a == i64::MIN { 0 } else { a } + i - x) + } else { + a = (a + i).max(if b == i64::MIN { 0 } else { b } + i - x) + } + } + + a.max(b) + } +} diff --git a/src/bin/w3tCBm.rs b/src/bin/w3tCBm.rs new file mode 100644 index 00000000..61c2ea9a --- /dev/null +++ b/src/bin/w3tCBm.rs @@ -0,0 +1,27 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() { + assert_eq!(Solution::count_bits(2), vec![0, 1, 1]); + assert_eq!(Solution::count_bits(5), vec![0, 1, 1, 2, 1, 2]); +} + +struct Solution; + +impl Solution { + pub fn count_bits(n: i32) -> Vec { + let mut ans = vec![0; n as usize + 1]; + let mut start = 0; + let mut pow = 1; + for i in 1..=n { + if i == pow { + start = 0; + pow <<= 1; + } + + ans[i as usize] = ans[start] + 1; + start += 1; + } + + ans + } +} diff --git a/src/bin/walking-robot-simulation.rs b/src/bin/walking-robot-simulation.rs new file mode 100644 index 00000000..d583dbc8 --- /dev/null +++ b/src/bin/walking-robot-simulation.rs @@ -0,0 +1,85 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn robot_sim(commands: Vec, obstacles: Vec>) -> i32 { + enum Direction { + East, + South, + West, + North, + } + + let hashset: std::collections::HashSet<_> = + obstacles.into_iter().map(|x| (x[0], x[1])).collect(); + + let (mut p1, mut p2) = (0, 0); + let mut result = 0; + + let mut direction = Direction::North; + + for i in commands { + match i { + -2 => match direction { + Direction::East => direction = Direction::North, + Direction::South => direction = Direction::East, + Direction::West => direction = Direction::South, + Direction::North => direction = Direction::West, + }, + -1 => match direction { + Direction::East => direction = Direction::South, + Direction::South => direction = Direction::West, + Direction::West => direction = Direction::North, + Direction::North => direction = Direction::East, + }, + step => match direction { + Direction::East => { + for i in 0..step { + if hashset.contains(&(p1 + 1, p2)) { + break; + } + p1 += 1; + + result = result.max(p1 * p1 + p2 * p2); + } + } + Direction::South => { + for i in 0..step { + if hashset.contains(&(p1, p2 - 1)) { + break; + } + p2 -= 1; + + result = result.max(p1 * p1 + p2 * p2); + } + } + Direction::West => { + for i in 0..step { + if hashset.contains(&(p1 - 1, p2)) { + break; + } + p1 -= 1; + + result = result.max(p1 * p1 + p2 * p2); + } + } + Direction::North => { + for i in 0..step { + if hashset.contains(&(p1, p2 + 1)) { + break; + } + p2 += 1; + + result = result.max(p1 * p1 + p2 * p2); + } + } + }, + } + } + + result + } +} diff --git a/src/bin/water-and-jug-problem.rs b/src/bin/water-and-jug-problem.rs new file mode 100644 index 00000000..984e72ee --- /dev/null +++ b/src/bin/water-and-jug-problem.rs @@ -0,0 +1,91 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn can_measure_water(jug1_capacity: i32, jug2_capacity: i32, target_capacity: i32) -> bool { + let mut set = std::collections::HashSet::<(i32, i32)>::new(); + + Self::dfs( + jug1_capacity, + jug2_capacity, + target_capacity, + 0, + 0, + &mut set, + ) + } + + fn dfs( + jug1_capacity: i32, + jug2_capacity: i32, + target_capacity: i32, + current_1: i32, + current_2: i32, + set: &mut std::collections::HashSet<(i32, i32)>, + ) -> bool { + if set.contains(&(current_1, current_2)) { + return false; + } + set.insert((current_1, current_2)); + + if current_1 == target_capacity + || current_2 == target_capacity + || current_1 + current_2 == target_capacity + { + return true; + } + + // 1清空 + // 2清空 + // 1装满 + // 2装满 + // 1到给2 + // 2到给1 + Self::dfs( + jug1_capacity, + jug2_capacity, + target_capacity, + 0, + current_2, + set, + ) || Self::dfs( + jug1_capacity, + jug2_capacity, + target_capacity, + current_1, + 0, + set, + ) || Self::dfs( + jug1_capacity, + jug2_capacity, + target_capacity, + jug1_capacity, + current_2, + set, + ) || Self::dfs( + jug1_capacity, + jug2_capacity, + target_capacity, + current_1, + jug2_capacity, + set, + ) || Self::dfs( + jug1_capacity, + jug2_capacity, + target_capacity, + current_1 - (jug2_capacity - current_2).max(0).min(current_1), + current_2 + (jug2_capacity - current_2).max(0).min(current_1), + set, + ) || Self::dfs( + jug1_capacity, + jug2_capacity, + target_capacity, + current_1 + (jug1_capacity - current_1).max(0).min(jug2_capacity), + jug2_capacity - (jug1_capacity - current_1).max(0).min(jug2_capacity), + set, + ) + } +} diff --git a/src/bin/water-bottles.rs b/src/bin/water-bottles.rs new file mode 100644 index 00000000..dbd4a317 --- /dev/null +++ b/src/bin/water-bottles.rs @@ -0,0 +1,20 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + assert_eq!(19, Solution::num_water_bottles(15, 4)); +} + +struct Solution; + +impl Solution { + pub fn num_water_bottles(mut num_bottles: i32, num_exchange: i32) -> i32 { + let mut a = num_bottles; // 剩余的空瓶 + + while a >= num_exchange { + num_bottles += 1; // 瓶数加1 + a -= num_exchange; // 空瓶数减num_exchange + a += 1; // 瓶数加1 + } + num_bottles + } +} diff --git a/src/bin/watering-plants-ii.rs b/src/bin/watering-plants-ii.rs new file mode 100644 index 00000000..8ec042b7 --- /dev/null +++ b/src/bin/watering-plants-ii.rs @@ -0,0 +1,38 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn minimum_refill(plants: Vec, capacity_a: i32, capacity_b: i32) -> i32 { + let mut result = 0; + let (mut a, mut b) = (capacity_a, capacity_b); + let (mut i, mut j) = (0, plants.len() - 1); + while i <= j { + if i == j { + if a < plants[i] && b < plants[i] { + result += 1; + } + break; + } else { + if a < plants[i] { + a = capacity_a; + result += 1; + } + + if b < plants[j] { + b = capacity_b; + result += 1; + } + + a -= plants[i]; + b -= plants[j]; + i += 1; + j -= 1; + } + } + + result + } +} diff --git a/src/bin/watering-plants.rs b/src/bin/watering-plants.rs new file mode 100644 index 00000000..aeac789a --- /dev/null +++ b/src/bin/watering-plants.rs @@ -0,0 +1,24 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn watering_plants(plants: Vec, capacity: i32) -> i32 { + let mut current_capacity = capacity; + let mut result = 0; + for i in 0..plants.len() { + result += 1; + if current_capacity < plants[i] { + current_capacity = capacity; + result += i as i32 * 2; + } + + current_capacity -= plants[i]; + } + + result + } +} +https://leetcode.cn/problems/watering-plants-ii/description/?envType=daily-question&envId=2024-05-09 \ No newline at end of file diff --git a/src/bin/wiggle-subsequence.rs b/src/bin/wiggle-subsequence.rs new file mode 100644 index 00000000..87f8edf5 --- /dev/null +++ b/src/bin/wiggle-subsequence.rs @@ -0,0 +1,26 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn wiggle_max_length(nums: Vec) -> i32 { + // 当长度小于等于2时,就可能为1或者2,结果取决与长度 + if nums.len() <= 1 { + return nums.len() as i32; + } + + let (mut down, mut up) = (1, 1); + + for i in 1..nums.len() { + if nums[i] > nums[i - 1] { + up = down + 1; + } else if nums[i] < nums[i - 1] { + down = up + 1; + } + } + + down.max(up) + } +} diff --git a/src/bin/word-break.rs b/src/bin/word-break.rs new file mode 100644 index 00000000..3ba2e2bc --- /dev/null +++ b/src/bin/word-break.rs @@ -0,0 +1,36 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + /// dp[i]表示s[0..i]是否满足 + /// dp[j] 是否满足取决于dp[0] —> dp[j-n] 和 s[j-n..j]是否满足 + pub fn word_break(s: String, word_dict: Vec) -> bool { + let mut n = s.len(); + + let hash = word_dict + .iter() + .map(|x| &x[..]) + .collect::>(); + let mut dp = vec![false; n]; + dp[0] = hash.contains(&s[0..1]); + + for i in 1..n { + if (dp[i - 1] && hash.contains(&s[i..i + 1])) || hash.contains(&s[0..i + 1]) { + dp[i] = true; + continue; + } + + for j in 0..i { + dp[i] = dp[j] && hash.contains(&s[j + 1..i + 1]); + if dp[i] { + break; + } + } + } + + dp[dp.len() - 1] + } +} diff --git a/src/bin/word-pattern.rs b/src/bin/word-pattern.rs new file mode 100644 index 00000000..21fdf99f --- /dev/null +++ b/src/bin/word-pattern.rs @@ -0,0 +1,37 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn word_pattern(pattern: String, s: String) -> bool { + let mut m = std::collections::HashMap::::new(); + let mut m1 = std::collections::HashMap::<&str, u8>::new(); + let s = s.split(' ').collect::>(); + let pattern = pattern.as_bytes(); + + if s.len() != pattern.len() { + return false; + } + + for i in 0..s.len() { + if let Some(&v) = m1.get(&s[i]) { + if v != pattern[i] { + return false; + } + } + + if let Some(&v) = m.get(&pattern[i]) { + if v != s[i] { + return false; + } + } + + m1.insert(s[i], pattern[i]); + m.insert(pattern[i], s[i]); + } + + true + } +} diff --git a/src/bin/word-search.rs b/src/bin/word-search.rs new file mode 100644 index 00000000..a7a1dea6 --- /dev/null +++ b/src/bin/word-search.rs @@ -0,0 +1,83 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn exist(board: Vec>, word: String) -> bool { + let word = word.as_bytes(); + let mut board = board; + + for i in 0..board.len() { + for j in 0..board[0].len() { + if board[i][j] as u8 == word[0] { + let x = board[i][j]; + board[i][j] = '0'; + if Self::scan(&mut board[..], &word[1..], (i, j)) { + return true; + } + board[i][j] = x; + } + } + } + + false + } + + fn scan(board: &mut [Vec], word: &[u8], index: (usize, usize)) -> bool { + if word.len() == 0 { + return true; + } + + if index.0 > 0 { + let x = board[index.0 - 1][index.1]; + board[index.0 - 1][index.1] = '0'; + if x != '0' + && x as u8 == word[0] + && Self::scan(board, &word[1..], (index.0 - 1, index.1)) + { + return true; + } + board[index.0 - 1][index.1] = x; + } + + if index.0 < board.len() - 1 { + let x = board[index.0 + 1][index.1]; + board[index.0 + 1][index.1] = '0'; + if x != '0' + && x as u8 == word[0] + && Self::scan(board, &word[1..], (index.0 + 1, index.1)) + { + return true; + } + board[index.0 + 1][index.1] = x; + } + + if index.1 > 0 { + let x = board[index.0][index.1 - 1]; + board[index.0][index.1 - 1] = '0'; + if x != '0' + && x as u8 == word[0] + && Self::scan(board, &word[1..], (index.0, index.1 - 1)) + { + return true; + } + board[index.0][index.1 - 1] = x; + } + + if index.1 < board[0].len() - 1 { + let x = board[index.0][index.1 + 1]; + board[index.0][index.1 + 1] = '0'; + if x != '0' + && x as u8 == word[0] + && Self::scan(board, &word[1..], (index.0, index.1 + 1)) + { + return true; + } + board[index.0][index.1 + 1] = x; + } + + false + } +} diff --git a/src/bin/wtcaE1.rs b/src/bin/wtcaE1.rs new file mode 100644 index 00000000..775b38c7 --- /dev/null +++ b/src/bin/wtcaE1.rs @@ -0,0 +1,32 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() { + assert_eq!(Solution::length_of_longest_substring("abcabcbb".into()), 3); + assert_eq!(Solution::length_of_longest_substring("bbbbb".into()), 1); + assert_eq!(Solution::length_of_longest_substring("pwwkew".into()), 3); +} + +struct Solution; + +impl Solution { + /// 使用set来判断是否已经存在,如果存在的话,移动p直到把重复的元素移除为止 + /// abcabcbb + /// 如果当前下标为4,p需要移动到2,也就是把重复的b字符移除为止,这时就不包含重复的字符了。 + pub fn length_of_longest_substring(s: String) -> i32 { + let mut set = std::collections::HashSet::new(); + let mut ans = 0; + let mut p = 0; + + for i in 0..s.len() { + while set.contains(&(s.as_bytes()[i])) { + set.remove(&(s.as_bytes()[p])); + p += 1; + } + + set.insert(s.as_bytes()[i]); + ans = ans.max(i - p + 1); + } + + ans as i32 + } +} diff --git a/src/bin/x-of-a-kind-in-a-deck-of-cards.rs b/src/bin/x-of-a-kind-in-a-deck-of-cards.rs new file mode 100644 index 00000000..4cff0064 --- /dev/null +++ b/src/bin/x-of-a-kind-in-a-deck-of-cards.rs @@ -0,0 +1,30 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn has_groups_size_x(deck: Vec) -> bool { + let mut h = std::collections::HashMap::new(); + for i in deck { + h.entry(i).and_modify(|x| *x += 1).or_insert(1); + } + + let mut max = 0; + + for (_, j) in h { + max = Self::gcd(max, j); + } + + max >= 2 + } + + fn gcd(a: i32, b: i32) -> i32 { + if a == 0 { + b + } else { + Self::gcd(b % a, a) + } + } +} diff --git a/src/bin/xoh6Oh.rs b/src/bin/xoh6Oh.rs new file mode 100644 index 00000000..c3ad2c0a --- /dev/null +++ b/src/bin/xoh6Oh.rs @@ -0,0 +1,48 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() { + println!("{}", Solution::divide(15, 2)); + println!("{}", Solution::divide(-7, 3)); + println!("{}", Solution::divide(7, -3)); + println!("{}", Solution::divide(-2, 3)); + println!("{}", Solution::divide(0, 3)); +} + +struct Solution; + +impl Solution { + pub fn divide(a: i32, b: i32) -> i32 { + let mut sign: i64 = if a.signum() == b.signum() { 1 } else { -1 }; + + let mut a = if a > 0 { a as i64 } else { 0 - a as i64 }; + let mut b = if b > 0 { b as i64 } else { 0 - b as i64 }; + + let mut ans = 0 as i64; + let mut r = 1; + let mut new_b = b; + loop { + if a < b { + break; + } + + if a < new_b + new_b { + ans += r; + a -= new_b; + r = 1; + new_b = b; + continue; + } + + new_b += new_b; + r += r; + } + + let ans = if sign == 1 { ans } else { 0 - ans }; + + if ans > i32::MAX as i64 { + i32::MAX + } else { + ans as i32 + } + } +} diff --git a/src/bin/xuan-zhuan-shu-zu-de-zui-xiao-shu-zi-lcof.rs b/src/bin/xuan-zhuan-shu-zu-de-zui-xiao-shu-zi-lcof.rs new file mode 100644 index 00000000..bd005c7b --- /dev/null +++ b/src/bin/xuan-zhuan-shu-zu-de-zui-xiao-shu-zi-lcof.rs @@ -0,0 +1,24 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + pub fn min_array(numbers: Vec) -> i32 { + let (mut start, mut end) = (0, numbers.len() - 1); + + while start < end { + let middile = start + (end - start) / 2; + if numbers[middile] < numbers[end] { + end = middile; + } else if numbers[middile] > numbers[end] { + start = middile + 1; + } else { + end -= 1; + } + } + + numbers[start] + } +} diff --git a/src/bin/yong-liang-ge-zhan-shi-xian-dui-lie-lcof.rs b/src/bin/yong-liang-ge-zhan-shi-xian-dui-lie-lcof.rs index 9a0c4799..fcfca4fb 100644 --- a/src/bin/yong-liang-ge-zhan-shi-xian-dui-lie-lcof.rs +++ b/src/bin/yong-liang-ge-zhan-shi-xian-dui-lie-lcof.rs @@ -1,3 +1,5 @@ +#![allow(dead_code, unused, unused_variables)] + /// 思路: /// 栈stack1用来存放插入的数据 /// 栈stack2用来存放删除的数据 @@ -12,7 +14,6 @@ struct CQueue { stack2: Vec, } - /** * `&self` means the method takes an immutable reference. * If you need a mutable reference, change it to `&mut self` instead. @@ -56,4 +57,4 @@ impl CQueue { } } -fn main() {} \ No newline at end of file +fn main() {} diff --git a/src/bin/yuan-quan-zhong-zui-hou-sheng-xia-de-shu-zi-lcof.rs b/src/bin/yuan-quan-zhong-zui-hou-sheng-xia-de-shu-zi-lcof.rs new file mode 100644 index 00000000..695835ff --- /dev/null +++ b/src/bin/yuan-quan-zhong-zui-hou-sheng-xia-de-shu-zi-lcof.rs @@ -0,0 +1,34 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + /// 倒推法 + /// n等于1时,一定返回下标为0的 + /// 最后一个元素的下标一定会一直往前移动m位,即f(n-1)的下标为f(n) - m,因此f(n) = f(n-1) + m + /// 又因为会溢出,所以需要对n取模,所以f(n) = (f(n-1) + m) % n + pub fn last_remaining(n: i32, m: i32) -> i32 { + let mut v = 0; + + for i in 2..n + 1 { + v = (v + m) % i; + } + + v + } + + pub fn last_remaining_1(n: i32, m: i32) -> i32 { + let mut v = (0..n).collect::>(); + + let mut index = 0; // 开始的索引,开始从0计数 + while v.len() > 1 { + index = (index + m as usize - 1) % v.len(); + + v.remove(index); + } + + v[0] + } +} diff --git a/src/bin/zai-pai-xu-shu-zu-zhong-cha-zhao-shu-zi-lcof.rs b/src/bin/zai-pai-xu-shu-zu-zhong-cha-zhao-shu-zi-lcof.rs new file mode 100644 index 00000000..2472692d --- /dev/null +++ b/src/bin/zai-pai-xu-shu-zu-zhong-cha-zhao-shu-zi-lcof.rs @@ -0,0 +1,44 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() {} + +struct Solution; + +impl Solution { + // 二分法 + // 找到第一个数和最后一个数的下标,相减得到数量 + pub fn search(nums: Vec, target: i32) -> i32 { + let (mut start, mut end) = (0, nums.len()); + let (mut left, mut right) = (0, 0); + + // 搜索右边界 + while start < end { + let middle = (end + start) / 2; + + if nums[middle] <= target { + start = middle + 1; + } else { + end = middle; + } + } + + right = start as i32; + + let (mut start, mut end) = (0, nums.len()); + + // 搜索左边界 + while start < end { + let middle = (end + start) / 2; + + if nums[middle] >= target { + end = middle; + } else { + start = middle + 1; + } + } + + left = start as i32; + + right - left + } +} diff --git a/src/bin/zhan-de-ya-ru-dan-chu-xu-lie-lcof.rs b/src/bin/zhan-de-ya-ru-dan-chu-xu-lie-lcof.rs new file mode 100644 index 00000000..8fac2730 --- /dev/null +++ b/src/bin/zhan-de-ya-ru-dan-chu-xu-lie-lcof.rs @@ -0,0 +1,60 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() { + println!( + "{}", + Solution::validate_stack_sequences(vec![1, 2, 3, 4, 5], vec![4, 5, 3, 2, 1]) + ); + + println!( + "{}", + Solution::validate_stack_sequences(vec![1, 2, 3, 4, 5], vec![4, 3, 5, 1, 2]) + ); +} + +struct Solution; + +impl Solution { + pub fn validate_stack_sequences1(pushed: Vec, popped: Vec) -> bool { + let (mut index1, mut index2) = (0, 0); + let mut stack = vec![]; + + while index1 < pushed.len() || index2 < pushed.len() { + if index1 < pushed.len() + && (stack.is_empty() || *stack.last().unwrap() != popped[index2]) + { + stack.push(pushed[index1]); + index1 += 1; + } else { + match stack.pop() { + Some(x) if x == popped[index2] => { + index2 += 1; + } + _ => return false, + } + } + } + + stack.is_empty() + } + + pub fn validate_stack_sequences(pushed: Vec, popped: Vec) -> bool { + let mut index = 0; + let mut stack = vec![]; + + for i in pushed { + stack.push(i); + + while let Some(&x) = stack.last() { + if x == popped[index] { + stack.pop(); + index += 1; + } else { + break; + } + } + } + + stack.is_empty() + } +} diff --git a/src/bin/zhong-jian-er-cha-shu-lcof.rs b/src/bin/zhong-jian-er-cha-shu-lcof.rs new file mode 100644 index 00000000..fc487dfc --- /dev/null +++ b/src/bin/zhong-jian-er-cha-shu-lcof.rs @@ -0,0 +1,92 @@ +#![allow(dead_code, unused, unused_variables)] + +use std::cell::RefCell; +use std::rc::Rc; + +fn main() { + println!( + "{:?}", + Solution::build_tree(vec![3, 9, 20, 15, 7], vec![9, 3, 15, 20, 7]) + ); + println!("{:?}", Solution::build_tree(vec![1, 2], vec![1, 2])); +} + +struct Solution; + +// Definition for a binary tree node. +#[derive(Debug, PartialEq, Eq)] +pub struct TreeNode { + pub val: i32, + pub left: Option>>, + pub right: Option>>, +} + +impl TreeNode { + #[inline] + pub fn new(val: i32) -> Self { + TreeNode { + val, + left: None, + right: None, + } + } +} + +impl Solution { + pub fn build_tree(preorder: Vec, inorder: Vec) -> Option>> { + if preorder.is_empty() { + return None; + } + + let index = inorder + .iter() + .enumerate() + .map(|(x, &y)| (y, x)) + .collect::>(); + + Self::build( + &preorder, + &inorder, + (0, preorder.len() - 1), + (0, inorder.len() - 1), + &index, + ) + } + + fn build( + preorder: &Vec, + inorder: &Vec, + preorder_index: (usize, usize), + inorder_index: (usize, usize), + index: &std::collections::HashMap, + ) -> Option>> { + if preorder_index.0 > preorder_index.1 { + return None; + } + + let root_value = preorder[preorder_index.0]; + let &root_index = index.get(&root_value).unwrap(); + let left_len = root_index - inorder_index.0; + let node = Rc::new(RefCell::new(TreeNode::new(root_value))); + + if root_index > 0 { + node.borrow_mut().left = Self::build( + preorder, + inorder, + (preorder_index.0 + 1, (preorder_index.0 + left_len)), + (inorder_index.0, (root_index - 1)), + index, + ); + } + + node.borrow_mut().right = Self::build( + preorder, + inorder, + (preorder_index.0 + left_len + 1, preorder_index.1), + (root_index + 1, inorder_index.1), + index, + ); + + Some(node) + } +} diff --git a/src/bin/zi-fu-chuan-de-pai-lie-lcof.rs b/src/bin/zi-fu-chuan-de-pai-lie-lcof.rs new file mode 100644 index 00000000..ed40f6df --- /dev/null +++ b/src/bin/zi-fu-chuan-de-pai-lie-lcof.rs @@ -0,0 +1,86 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +use std::vec; + +fn main() { + println!("{:?}", Solution::permutation("abc".to_string())); +} + +struct Solution; + +impl Solution { + pub fn permutation1(s: String) -> Vec { + Self::f(s.as_bytes()) + .into_iter() + .map(|x| String::from_utf8(x).unwrap()) + .collect::>() + .into_iter() + .collect() + } + + fn f(x: &[u8]) -> Vec> { + if x.len() == 1 { + return vec![vec![x[0]]]; + } + let mut data = vec![]; + for i in 0..x.len() { + let n = x[i]; + let mut v = Vec::with_capacity(x.len()); + v.extend(&x[0..i]); + v.extend(&x[i + 1..]); + + let x1 = Self::f(&v[..]); + for j in x1.iter() { + let mut m = Vec::with_capacity(x.len()); + m.push(n); + m.extend(j.into_iter()); + data.push(m); + } + } + + data + } + + pub fn permutation(s: String) -> Vec { + let mut s = s; + unsafe { + let bytes = s.as_bytes_mut(); + bytes.sort(); + } + + let mut data = vec![s]; + let mut index = 0; + + while index < data.len() { + match Self::next_permutation(data[index].clone()) { + Some(s) => data.push(s), + None => break, + } + index += 1; + } + + data + } + + pub fn next_permutation(mut string: String) -> Option { + unsafe { + let s = string.as_bytes_mut(); + for i in (0..s.len() - 1).rev() { + if s[i] < s[i + 1] { + let mut min = i + 1; + for j in (i + 1..s.len()).rev() { + if s[j] > s[i] && s[j] < s[min] { + min = j; + } + } + s.swap(i, min); + s[i + 1..].sort(); + + return Some(string); + } + } + + None + } + } +} diff --git a/src/bin/zigzag-conversion.rs b/src/bin/zigzag-conversion.rs new file mode 100644 index 00000000..81b6cf98 --- /dev/null +++ b/src/bin/zigzag-conversion.rs @@ -0,0 +1,48 @@ +#![allow(dead_code, unused, unused_variables)] + +fn main() { + // assert_eq!(Solution::convert("LEETCODEISHIRINGS".to_string(), 4), "LDREOEIIECIHNSTSG".to_string()); + assert_eq!(Solution::convert("AB".to_string(), 1), "AB".to_string()); +} + +struct Solution; + +impl Solution { + /// s = "LEETCODEISHIRINGS", numRows = 4 + /// 输出: "LDREOEIIECIHNSTSG" + /// L D R + /// E O E I I + /// E C I H N S + /// T S G + /// + /// s = "LEETCODEISHIRINGS", numRows = 5 + /// 输出:"LISEESGEDHNTOIICR" + /// + /// L I S + /// E E S G + /// E D H N + /// T O I I + /// C R + pub fn convert(s: String, num_rows: i32) -> String { + if num_rows == 1 { + return s; + } + + let s = s.chars().into_iter().collect::>(); + let mut s1 = Vec::::with_capacity(s.len()); + let num = num_rows as usize * 2 - 2; // 把v字形看成一组。则num代表一组的成员 + + for i in 0..=num_rows as usize - 1 { + let mut index = i as usize; + while index < s.len() { + s1.push(s[index]); + index += num; + if i != 0 && i != num_rows as usize - 1 && index - 2 * i < s.len() { + s1.push(s[index - 2 * i]); + } + } + } + + s1.into_iter().collect::() + } +} diff --git a/src/bin/zui-chang-bu-han-zhong-fu-zi-fu-de-zi-zi-fu-chuan-lcof.rs b/src/bin/zui-chang-bu-han-zhong-fu-zi-fu-de-zi-zi-fu-chuan-lcof.rs new file mode 100644 index 00000000..c59f450f --- /dev/null +++ b/src/bin/zui-chang-bu-han-zhong-fu-zi-fu-de-zi-zi-fu-chuan-lcof.rs @@ -0,0 +1,38 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +fn main() { + assert_eq!(3, Solution::length_of_longest_substring("abcabcbb".into())); + assert_eq!(1, Solution::length_of_longest_substring("bbbbb".into())); + assert_eq!(3, Solution::length_of_longest_substring("pwwkew".into())); + assert_eq!(2, Solution::length_of_longest_substring("au".into())); + assert_eq!(2, Solution::length_of_longest_substring("aab".into())); + assert_eq!(3, Solution::length_of_longest_substring("dvdf".into())); + assert_eq!(5, Solution::length_of_longest_substring("tmmzuxt".into())); +} + +struct Solution; + +impl Solution { + pub fn length_of_longest_substring(s: String) -> i32 { + let mut hash = std::collections::HashMap::new(); + let (mut start, mut length, mut result) = (0, 0, 0); + + for (index, value) in s.as_bytes().into_iter().enumerate() { + if let Some(i) = hash.get_mut(value) { + if start < *i { + start = *i; + } + + length = index - start; + *i = index; + } else { + hash.insert(value, index); + length += 1; + } + + result = result.max(length); + } + + result as i32 + } +} diff --git a/src/bin/zui-xiao-de-kge-shu-lcof.rs b/src/bin/zui-xiao-de-kge-shu-lcof.rs new file mode 100644 index 00000000..e104455f --- /dev/null +++ b/src/bin/zui-xiao-de-kge-shu-lcof.rs @@ -0,0 +1,67 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +use std::{iter::FromIterator, vec}; + +fn main() { + println!("{:?}", Solution::get_least_numbers(vec![3, 2, 1], 2)); + println!("{:?}", Solution::get_least_numbers(vec![0, 1, 2, 1], 1)); + println!("{:?}", Solution::get_least_numbers((0..100).collect(), 15)); + println!( + "{:?}", + Solution::get_least_numbers(vec![0, 0, 1, 2, 4, 2, 2, 3, 1, 4], 8) + ); +} + +/// 大顶堆 +struct Heap { + data: Vec, + len: usize, +} + +struct Solution; + +impl Solution { + pub fn get_least_numbers(mut arr: Vec, k: i32) -> Vec { + Self::quick_sort(&mut arr, k as usize); + (&arr[0..k as usize]).to_vec() + } + + pub fn quick_sort(arr: &mut [i32], k: usize) { + if arr.len() <= 1 || k == 0 { + return; + } + + let (mut base, mut begin, mut end) = (arr[0], 0, arr.len() - 1); + while begin < end { + while begin < end { + if arr[end] > base { + end -= 1; + } else { + arr.swap(begin, end); + begin += 1; + break; + } + } + + while begin < end { + if arr[begin] < base { + begin += 1; + } else { + arr.swap(begin, end); + end -= 1; + break; + } + } + } + + arr[begin] = base; + // [1,2,3,4,5] k=1 begin=2 + if begin == k || begin + 1 == k { + return; + } else if begin >= 1 + k { + Self::quick_sort(&mut arr[..begin], k); + } else { + Self::quick_sort(&mut arr[begin + 1..], k - begin - 1); + } + } +} diff --git a/src/bin/zuo-xuan-zhuan-zi-fu-chuan-lcof.rs b/src/bin/zuo-xuan-zhuan-zi-fu-chuan-lcof.rs new file mode 100644 index 00000000..c9cec9c6 --- /dev/null +++ b/src/bin/zuo-xuan-zhuan-zi-fu-chuan-lcof.rs @@ -0,0 +1,19 @@ +#![allow(dead_code, unused, unused_variables, non_snake_case)] + +use std::{io::Read, vec}; + +fn main() {} + +struct Solution; + +impl Solution { + pub fn reverse_left_words(s: String, n: i32) -> String { + let mut r = Vec::with_capacity(s.len()); + let bytes = s.as_bytes(); + for i in (n as usize..(n as usize + s.len())) { + r.push(bytes[i % s.len()]); + } + + String::from_utf8(r).unwrap() + } +} diff --git a/src/file.rs b/src/file.rs new file mode 100644 index 00000000..caec830c --- /dev/null +++ b/src/file.rs @@ -0,0 +1,129 @@ +use lazy_static::lazy_static; +use regex::Regex; +use tokio::fs::{self, File}; +use tokio::io::AsyncWriteExt; +use tokio_stream::wrappers::ReadDirStream; +use tokio_stream::StreamExt; + +use crate::http::{Data, Difficulty, Ques, Resp}; + +lazy_static! { + static ref RE: Regex = + Regex::new(r"\|\s*([0-9]*)\s*\|\s*(.*?)\s*\|.*?bin/(.*?)\.rs.*?\|.*?\|\s*?(\w*)\s*?\|") + .unwrap(); +} + +/// 将结果写入README.md中 +pub async fn write_readme(r: &mut Vec) { + // 先按id排序 + r.sort_by(|x, y| { + let x_id = x.data.question.question_id.parse::().unwrap(); + let y_id = y.data.question.question_id.parse::().unwrap(); + x_id.cmp(&y_id) + }); + let s = crate::render::render(r).unwrap(); + + match tokio::fs::write("README.md", s).await { + Ok(_) => (), + Err(e) => eprintln!("写入 README.md 失败,err{}", e.to_string()), + } +} + +/// 获取 src/bin 目录下所有文件的名称 +pub async fn get_all_bin_file() -> Vec { + let mut dir = ReadDirStream::new(fs::read_dir("src/bin/").await.unwrap()); + let mut v = vec![]; + while let Some(x) = dir.next().await { + v.push( + x.unwrap() + .file_name() + .to_str() + .unwrap() + .trim_end_matches(".rs") + .to_string(), + ); + } + + v +} + +/// 创建 bin/{quest_name}.rs 文件 +pub async fn write_question(resp: Resp) { + let file = format!("src/bin/{}.rs", resp.data.question.title_slug); + if std::path::Path::new(file.as_str()).exists() { + eprintln!("{} exists", file); + return; + } + + let mut f = File::create(file.as_str()).await.unwrap(); + let mut s = String::new(); + s.push_str("#![allow(dead_code, unused, unused_variables, non_snake_case)]\n\n"); + s.push_str("fn main() {}\n\n"); + s.push_str("struct Solution;\n\n"); + + for i in resp.data.question.code_snippets { + if i.lang == "Rust" { + s.push_str(i.code.replace("↵", "\n").as_str()); + s.push('\n'); + break; + } + } + + f.write_all(s.as_bytes()).await.unwrap(); +} + +/// 解析README.md +pub async fn parse_readme() -> Vec { + let contents = fs::read_to_string("README.md").await.unwrap(); + parse(&contents) +} + +fn parse(contents: &str) -> Vec { + let mut v = vec![]; + for content in contents.split('\n') { + for i in RE.captures_iter(content.trim()) { + v.push(Resp { + data: Data { + question: Ques { + question_id: i.get(1).unwrap().as_str().to_string(), + translated_title: i.get(2).unwrap().as_str().to_string(), + title_slug: i.get(3).unwrap().as_str().to_string(), + code_snippets: vec![], + difficulty: Difficulty::new(i.get(4).unwrap().as_str()), + }, + }, + }) + } + } + + v +} + +#[cfg(test)] +mod tests { + use super::get_all_bin_file; + use super::parse; + + #[tokio::test] + async fn test_parse_readme() { + let contents = tokio::fs::read_to_string("README.md").await.unwrap(); + let x = parse(&contents); + println!("{:?}", x); + println!("{}", x.len()); + + for i in x { + println!( + "{}, {}, {}, {:?}", + i.data.question.translated_title, + i.data.question.question_id, + i.data.question.title_slug, + i.data.question.difficulty + ); + } + } + + #[tokio::test] + async fn test_get_all_bin_file() { + println!("{:?}", get_all_bin_file().await); + } +} diff --git a/src/git.rs b/src/git.rs new file mode 100644 index 00000000..3e6a8f27 --- /dev/null +++ b/src/git.rs @@ -0,0 +1,60 @@ +use std::process::Command; + +use git2::{Repository, StatusOptions}; + +/// 把新文件加入到git中 +pub async fn push() { + // 解析readme.md文件 + let mut r = crate::file::parse_readme().await; + let new_file = get_uncommit_files(); + for i in new_file.iter() { + let x = i.trim_end_matches(".rs"); // 去掉后缀 + let x = x.trim_start_matches("src/bin/"); // 去掉路径 + git_add(i); + r.push(crate::http::get_question_info(x).await); + } + + crate::file::write_readme(&mut r).await; + git_add("README.md"); + push_to_origin(); +} + +fn get_uncommit_files() -> Vec { + let mut options = StatusOptions::new(); + options.pathspec("src/bin"); + options.include_untracked(true); + let repo = Repository::open(".").unwrap(); + let statuses = repo.statuses(Some(&mut options)).unwrap(); + + statuses + .iter() + .map(|x| String::from(x.path().unwrap())) + .collect() +} + +fn git_add(file: &str) { + Command::new("git").arg("add").arg(file).output().unwrap(); + let output = Command::new("git") + .arg("commit") + .arg("-m") + .arg(file) + .output() + .unwrap(); + + println!("{}", String::from_utf8(output.stdout).unwrap()); +} + +pub fn push_to_origin() { + let output = Command::new("git").arg("push").output().unwrap(); + println!("{}", String::from_utf8(output.stdout).unwrap()); +} + +#[cfg(test)] +mod tests { + use crate::git::get_uncommit_files; + + #[test] + fn test_get_uncommit_files() { + println!("{:?}", get_uncommit_files()); + } +} diff --git a/src/http.rs b/src/http.rs new file mode 100644 index 00000000..1316afd9 --- /dev/null +++ b/src/http.rs @@ -0,0 +1,153 @@ +use std::fmt; + +use lazy_static::lazy_static; +use regex::Regex; +use reqwest::Client; +use serde::de::{Error, Visitor}; +use serde::{Deserialize, Deserializer, Serialize, Serializer}; + +lazy_static! { + static ref RE: Regex = Regex::new(r".*?/problems/(.*?)/").unwrap(); +} + +const URL: &str = "https://leetcode.cn/graphql/"; + +#[derive(Debug, Eq, PartialEq)] +pub enum Difficulty { + Easy, + Medium, + Hard, +} + +impl Difficulty { + pub fn new(s: &str) -> Self { + match s { + "Easy" => Self::Easy, + "Medium" => Self::Medium, + "Hard" => Self::Hard, + _ => Self::Easy, + } + } +} + +impl Serialize for Difficulty { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + match self { + Self::Easy => serializer.serialize_str("Easy"), + Self::Medium => serializer.serialize_str("Medium"), + Self::Hard => serializer.serialize_str("Hard"), + } + } +} + +impl<'de> Deserialize<'de> for Difficulty { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct DifficultyVisitor; + + impl<'de> Visitor<'de> for DifficultyVisitor { + type Value = Difficulty; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + write!(formatter, "") + } + + fn visit_str(self, v: &str) -> Result + where + E: Error, + { + match v { + "Easy" => Ok(Self::Value::Easy), + "Medium" => Ok(Self::Value::Medium), + "Hard" => Ok(Self::Value::Hard), + _ => Err(Error::unknown_variant(v, &["Easy", "Medium", "Hard"])), + } + } + } + + deserializer.deserialize_str(DifficultyVisitor) + } +} + +#[derive(Deserialize, Serialize, Debug)] +pub struct Ques { + #[serde(rename = "questionId")] + pub question_id: String, + #[serde(rename = "titleSlug")] + pub title_slug: String, + #[serde(rename = "translatedTitle")] + pub translated_title: String, + #[serde(rename = "codeSnippets")] + pub code_snippets: Vec, + #[serde(rename = "difficulty")] + pub difficulty: Difficulty, +} + +#[derive(Deserialize, Serialize, Debug)] +pub struct CodeSnippets { + #[serde(rename = "code")] + pub code: String, + #[serde(rename = "lang")] + pub lang: String, + #[serde(rename = "langSlug")] + pub lang_slug: String, + #[serde(rename = "__typename", default)] + pub typename: String, +} + +#[derive(Deserialize, Serialize, Debug)] +pub struct Data { + pub question: Ques, +} + +#[derive(Deserialize, Serialize, Debug)] +pub struct Resp { + pub data: Data, +} + +pub async fn get_question_info(mut ques: &str) -> Resp { + if ques.starts_with("http") { + ques = RE + .captures_iter(ques) + .next() + .unwrap() + .get(1) + .unwrap() + .as_str(); + } + + let data_fmt = r#"{"operationName":"questionData","variables":{"titleSlug":"{}"}, + "query":"query questionData($titleSlug: String!) {\n question(titleSlug: $titleSlug) {\n questionId\n questionFrontendId\n boundTopicId\n title\n titleSlug\n content\n translatedTitle\n translatedContent\n isPaidOnly\n difficulty\n likes\n dislikes\n isLiked\n similarQuestions\n contributors {\n username\n profileUrl\n avatarUrl\n __typename\n }\n langToValidPlayground\n topicTags {\n name\n slug\n translatedName\n __typename\n }\n companyTagStats\n codeSnippets {\n lang\n langSlug\n code\n __typename\n }\n stats\n hints\n solution {\n id\n canSeeDetail\n __typename\n }\n status\n sampleTestCase\n metaData\n judgerAvailable\n judgeType\n mysqlSchemas\n enableRunCode\n envInfo\n book {\n id\n bookName\n pressName\n source\n shortDescription\n fullDescription\n bookImgUrl\n pressImgUrl\n productUrl\n __typename\n }\n isSubscribed\n isDailyQuestion\n dailyRecordStatus\n editorType\n ugcQuestionId\n style\n __typename\n }\n}\n"}"#; + + let data = data_fmt.replace("{}", ques); + + Client::new() + .post(URL) + .header("content-type", "application/json") + .body(data) + .send() + .await + .unwrap() + .json::() + .await + .expect(format!("{} download failed", ques).as_str()) +} + +#[cfg(test)] +mod tests { + use super::get_question_info; + + #[tokio::test] + async fn test_get_question_info() { + println!("{:?}", get_question_info("container-with-most-water").await); + println!( + "{:?}", + get_question_info("https://leetcode-cn.com/problems/container-with-most-water/").await + ); + } +} diff --git a/src/lib.rs b/src/lib.rs index 8fc900f5..5b844605 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,168 +1,40 @@ -#[cfg(test)] -mod tests { - use crate::{get_new_file_in_bin, get_question_msg, get_question_num}; - use super::*; - - #[test] - fn it_works() { - assert_eq!(2 + 2, 4); - } - - #[test] - fn test_get_new_file_in_bin() { - println!("{:?}", get_new_file_in_bin()); - } - - #[test] - fn test_get_question_num() { - assert_eq!(13usize, get_question_num()); - } - - #[test] - fn test_write_to_readme() { - let resp = get_question_msg("maximum-points-you-can-obtain-from-cards"); - write_to_readme(resp); - } - - #[test] - fn test_get_question_no() { - assert_eq!(374, get_question_no("- 374:猜数字大小")); - assert_eq!(367, get_question_no("- 367:有效的完全平方数")); - } -} - -extern crate reqwest; - -use git2::{Repository, StatusOptions}; -use serde::Deserialize; -use std::fs::{self, File}; -use std::io::Write; - - -/// 获取bin目录下新加的文件 -pub fn get_new_file_in_bin() -> Vec { - let mut options = StatusOptions::new(); - options.include_untracked(true); - let repo = Repository::open(".").unwrap(); - let statuses = repo.statuses(Some(&mut options)).unwrap(); - - statuses.iter(). - filter(|x| { x.path().unwrap().starts_with("src/bin/") }). - map(|x| String::from(x.path().unwrap())). - map(|x| { - let x = x.trim_end_matches(".rs"); // 去掉路径 - let x = x.trim_start_matches("src/bin/"); // 去掉后缀 - x.to_string() - }). - collect() -} - -#[derive(Deserialize, Debug)] -pub struct Ques { - #[serde(rename = "questionId")] - question_id: String, - #[serde(rename = "titleSlug")] - title_slug: String, - #[serde(rename = "translatedTitle")] - translated_title: String, -} - -#[derive(Deserialize, Debug)] -pub struct Data { - question: Ques, -} - -#[derive(Deserialize, Debug)] -pub struct Resp { - data: Data, -} - -/// 通过名字获取题目的ID -pub fn get_question_msg(name: &str) -> Resp { - let url = "https://leetcode-cn.com/graphql/"; - let data_fmt = r#"{"operationName":"questionData","variables":{"titleSlug":"{}"},"query":"query questionData($titleSlug: String!) {\n question(titleSlug: $titleSlug) {\n questionId\n questionFrontendId\n boundTopicId\n title\n titleSlug\n content\n translatedTitle\n translatedContent\n isPaidOnly\n difficulty\n likes\n dislikes\n isLiked\n similarQuestions\n contributors {\n username\n profileUrl\n avatarUrl\n __typename\n }\n langToValidPlayground\n topicTags {\n name\n slug\n translatedName\n __typename\n }\n companyTagStats\n codeSnippets {\n lang\n langSlug\n code\n __typename\n }\n stats\n hints\n solution {\n id\n canSeeDetail\n __typename\n }\n status\n sampleTestCase\n metaData\n judgerAvailable\n judgeType\n mysqlSchemas\n enableRunCode\n envInfo\n book {\n id\n bookName\n pressName\n source\n shortDescription\n fullDescription\n bookImgUrl\n pressImgUrl\n productUrl\n __typename\n }\n isSubscribed\n isDailyQuestion\n dailyRecordStatus\n editorType\n ugcQuestionId\n style\n __typename\n }\n}\n"}"#; - let data = data_fmt.replace("{}", name); - let res = reqwest::blocking::Client::new(). - post(url). - header("content-type", "application/json"). - body(data). - send(). - unwrap(). - json::().unwrap(); - - res -} - -/// 把问题写到README.md中 -pub fn write_to_readme(question_info: Resp) { - let readme = fs::read_to_string("README.md").unwrap(); - let mut write_string = String::new(); - write_string.push_str("# leetcode -通过rust刷leetcode题目。 -通过刷leetcode题目学习rust。\n\n"); - write_string.push_str(format!("当前已刷:{}\n\n", get_question_num()).as_str()); - write_string.push_str("### 题目\n"); - - let mut f = File::create("1.md").unwrap(); - - let mut index = 0usize; - let split = readme.split("\n").into_iter().collect::>(); - let mut flag = false; - let mut flag1 = false; - let no = question_info.data.question.question_id.parse::().unwrap(); - while index + 3 < split.len() { - if !flag { - if split[index] == "### 题目" { - flag = true; +use std::process; + +use clap::{App, Arg}; + +mod all; +mod file; +mod git; +mod http; +mod new; +mod render; + +pub async fn run() { + let matches = App::new("leetcode") + .version("0.0.1") + .author("bestgopher <84328409@qq.com>") + .about("a helper for leetcode") + .subcommand( + App::new("new").about("get a new leetcode question").arg( + Arg::new("question_name") + .help("The configuration file to use") + .index(1), + ), + ) + .subcommand(App::new("all").about("get all questions' info and rewrite README.md")) + .get_matches(); + + if let Some(matches) = matches.subcommand_matches("new") { + match matches.value_of_t::("question_name") { + Ok(x) => new::new(x).await, + Err(_) => { + eprintln!("please input the name of question"); + process::exit(1); } - index += 1; - continue; - } - - let i1 = get_question_no(split[index]); - if !flag1 && i1 > no { - flag1 = true; - write_string.push_str(format!("- {}:{}\n", no, question_info.data.question.translated_title).as_str()); - write_string.push_str(format!(" - [src](https://github.com/rustors/leetcode/blob/main/src/bin/{}.rs)\n", question_info.data.question.title_slug).as_str()); - write_string.push_str(format!(" - [leetcode](https://leetcode-cn.com/problems/{}/)\n", question_info.data.question.title_slug).as_str()); } - - write_string.push_str(format!("{}\n{}\n{}\n", split[index], split[index + 1], split[index + 2]).as_str()); - index += 3; + } else if matches.subcommand_matches("all").is_some() { + all::all().await; + } else { + git::push().await; } - - if !flag1 { - write_string.push_str(format!("- {}:{}\n", no, question_info.data.question.translated_title).as_str()); - write_string.push_str(format!(" - [src](https://github.com/rustors/leetcode/blob/main/src/bin/{}.rs)\n", question_info.data.question.title_slug).as_str()); - write_string.push_str(format!(" - [leetcode](https://leetcode-cn.com/problems/{}/)\n", question_info.data.question.title_slug).as_str()); - } - - let _ = f.write(write_string.as_bytes()); } - -/// 获取题目总数 -fn get_question_num() -> usize { - let dir = fs::read_dir("src/bin/").unwrap(); - - dir. - into_iter(). - filter(|x| { - if let Ok(f) = x { - f.file_name().to_str().unwrap().ends_with(".rs") - } else { - false - } - }).count() -} - -/// 获取题目的编号 -fn get_question_no(s: &str) -> i32 { - s.split(":") - .into_iter() - .collect::>()[0] - .trim_end_matches(':') - .trim_start_matches('-') - .trim_start() - .parse::() - .unwrap() -} \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 8efc0271..4748a86a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,13 +1,4 @@ -///! 根据src/bin中新加的题目生成相应的markdown文件 -use leetcode; -use leetcode::write_to_readme; - -fn main() { - // 获取新加的文件 - let files = leetcode::get_new_file_in_bin(); - - for i in files.iter() { - let res = leetcode::get_question_msg(i); - write_to_readme(res); - } +#[tokio::main] +async fn main() { + leetcode::run().await; } diff --git a/src/new.rs b/src/new.rs new file mode 100644 index 00000000..aacf7b54 --- /dev/null +++ b/src/new.rs @@ -0,0 +1,8 @@ +/// 1.获取question name +/// 2.如果name是url,就不需要拼装,不是就需要拼装 +/// 3.请求结构,获取数据 +/// 4.将数据写入bin/{question_name}.rs文件中 +pub async fn new(ques: String) { + let r = crate::http::get_question_info(ques.as_str()).await; + crate::file::write_question(r).await; +} diff --git a/src/render.rs b/src/render.rs new file mode 100644 index 00000000..6dfb1fe7 --- /dev/null +++ b/src/render.rs @@ -0,0 +1,77 @@ +use lazy_static::lazy_static; +use tera::{Context, Result as TeraResult, Tera}; + +/// 模板内容 +const TEMPLATE_STR: &str = r"# leetcode + +| Total | Easy | Medium | Hard | +| :----: | :----: | :----: | :----: | +| {{ datas | length }} | {{ easy_num }} | {{ medium_num }} | {{ hard_num }} | + +### 题目 + +| 编号 | 题目 | 代码 | 题目描述 | 难度 | +| ---- | ---- | ---- | ---- | ---- | +{% for t in datas %}|{{ t.data.question.questionId }} | {{ t.data.question.translatedTitle }} | [src](https://github.com/rustors/leetcode/blob/main/src/bin/{{ t.data.question.titleSlug }}.rs) | [leetcode](https://leetcode-cn.com/problems/{{ t.data.question.titleSlug }}/) | {{ t.data.question.difficulty }} | +{% endfor %}"; + +/// 模板名字 +const TEMPLATE_NAME: &str = "leetcode"; + +lazy_static!( + /// 用于渲染的模板 + pub static ref TEMPLATE: Tera = { + let mut tera = Tera::default(); + tera.add_raw_template(TEMPLATE_NAME, TEMPLATE_STR).unwrap(); + tera + }; +); + +/// 把传入的内容渲染为模板内容 +pub fn render(data: &[crate::http::Resp]) -> TeraResult { + let mut ctx = Context::new(); + + let easy_num = counter(data, |x| { + x.data.question.difficulty == crate::http::Difficulty::Easy + }); + let medium_num = counter(data, |x| { + x.data.question.difficulty == crate::http::Difficulty::Medium + }); + let hard_num = counter(data, |x| { + x.data.question.difficulty == crate::http::Difficulty::Hard + }); + + ctx.insert("datas", data); + ctx.insert("easy_num", &easy_num); + ctx.insert("medium_num", &medium_num); + ctx.insert("hard_num", &hard_num); + + TEMPLATE.render(TEMPLATE_NAME, &ctx) +} + +fn counter(data: &[crate::http::Resp], f: impl FnMut(&&crate::http::Resp) -> bool) -> usize { + data.into_iter().filter(f).count() +} + +#[cfg(test)] +mod tests { + use crate::http::{Data, Difficulty, Ques, Resp}; + use crate::render::render; + + #[test] + fn test_render() { + let data = vec![Resp { + data: Data { + question: Ques { + question_id: "111".to_string(), + title_slug: "aaa".to_string(), + translated_title: "中国".to_string(), + code_snippets: vec![], + difficulty: Difficulty::Easy, + }, + }, + }]; + + println!("{:?}", render(&data).unwrap().to_string()); + } +}