mirror of
https://github.com/halfrost/LeetCode-Go.git
synced 2025-07-07 01:44:56 +08:00
Compare commits
913 Commits
Author | SHA1 | Date | |
---|---|---|---|
3442d3a339 | |||
9437625832 | |||
e2a72e6212 | |||
aa0e2c897b | |||
f0d16fe32f | |||
e3bb5aff34 | |||
c5ed9a37e8 | |||
a655d95eea | |||
dff1d84e1e | |||
e227edf55a | |||
2a40f7cefb | |||
35a447cad6 | |||
30065c4b70 | |||
b94bef3b14 | |||
f9438b6c46 | |||
984772f724 | |||
200b30895c | |||
56d9c2ba75 | |||
2dcb43efa1 | |||
5ec282a5c7 | |||
51f6f2933e | |||
57544f8726 | |||
68ee68d28f | |||
5292b14fda | |||
0188b02705 | |||
47424f3384 | |||
2289321610 | |||
c114a326ac | |||
92f0db7400 | |||
c349d6cfaf | |||
4f91c4bd6d | |||
a2ac608eea | |||
ee626f37b4 | |||
2a1b7177be | |||
2163be2faf | |||
4decc5445c | |||
5273aaee57 | |||
4d869321a1 | |||
da59bd6b3b | |||
a7c216575f | |||
621fc00dcd | |||
9df639e4d1 | |||
4a8f5bdb25 | |||
f6d639b694 | |||
26eecfb08c | |||
715ab65012 | |||
6c05203809 | |||
ccde9a0e2c | |||
13943aeb59 | |||
235adcb11d | |||
57f9fa97af | |||
c4ef088d7f | |||
b5081cff9d | |||
98b537654f | |||
5797f77011 | |||
c76d68d21d | |||
54b6152ea3 | |||
bf4048d46a | |||
23dd9892d3 | |||
f6a2b87674 | |||
8b219118ac | |||
4fea0cb416 | |||
1e94b3b2ee | |||
56660e42f6 | |||
d12d4225b9 | |||
a160745e96 | |||
271ac63c53 | |||
c3c054f832 | |||
ab775bdacb | |||
4b746c2e7e | |||
0d1da6ae31 | |||
b1af73340f | |||
2e73dbad85 | |||
e85bad3027 | |||
0ecc089e36 | |||
a7907ebcc2 | |||
c217fa252c | |||
3f0ef3a415 | |||
b700ceafc1 | |||
3cb37345b8 | |||
8033b9055e | |||
8c353893f9 | |||
24f56bc288 | |||
1793f49397 | |||
6af31837d3 | |||
34d86c6628 | |||
1be6b990cc | |||
4d17c06e61 | |||
4ac8c07a23 | |||
41d8cfdfa6 | |||
afd978ad65 | |||
aeef5439f4 | |||
d0c38ea0d6 | |||
79387709eb | |||
21a9b98a14 | |||
c8d650f39b | |||
a850f0416b | |||
433db8452a | |||
a9bae7c776 | |||
e14059cc40 | |||
59a6ed04b5 | |||
3d14e94113 | |||
b4fa4ee93b | |||
bfa7319cab | |||
a4573f5439 | |||
0d50557121 | |||
b744248882 | |||
2473e3db76 | |||
b954a17720 | |||
f6fcb33e9d | |||
c5fcd07f72 | |||
6563b2d32a | |||
510fe9af7e | |||
0afe9d5ea9 | |||
f932b3f897 | |||
e8f35496e4 | |||
96d1c46897 | |||
d3e6d504d3 | |||
582d28f383 | |||
f8d2e25681 | |||
2155b7e2cd | |||
a328ec1724 | |||
a76dcda2d7 | |||
94c90621e2 | |||
b6628caf08 | |||
ba446ce792 | |||
ddb7d405e3 | |||
d7460199e7 | |||
56e82a8a76 | |||
91f22bb629 | |||
00f08ee280 | |||
de440ce31c | |||
f4bf65c12e | |||
efb609d0bc | |||
c90925cac1 | |||
cf62e8d88c | |||
0b541b8063 | |||
e8245d256d | |||
6713a1da43 | |||
f6f387c4c9 | |||
8d8825d5d7 | |||
fdbb97c38a | |||
aba0c0bb89 | |||
ace60c7085 | |||
0d49c4baa5 | |||
eda0ca97df | |||
6640124f1a | |||
6721273fd6 | |||
31309e5fc6 | |||
c790e94057 | |||
ce42db7424 | |||
67b2a804ad | |||
85933aba97 | |||
74793b40ff | |||
7ff53f5465 | |||
3e11abb6b4 | |||
cfac6e69e0 | |||
20ee68f12f | |||
866b482a59 | |||
b9d8019153 | |||
346d231e95 | |||
eed2d828a0 | |||
7bcbb5a0e5 | |||
66e605b559 | |||
e2dbc6377a | |||
4d68c22e37 | |||
2afd2968f0 | |||
5dbf391639 | |||
4fdf83b522 | |||
e76878e297 | |||
2e1ab89380 | |||
e5bbc2ea75 | |||
7f871503d6 | |||
acf7a8fc97 | |||
1cfe12d6ca | |||
e1d3d596fb | |||
98dc4bddd4 | |||
f6fe9d592d | |||
3fb28d858e | |||
92ec56c634 | |||
85060a4085 | |||
2e392abddf | |||
e55c6597ac | |||
025a7cb435 | |||
3581821e35 | |||
31a02a5c40 | |||
0de6b2993b | |||
dd97a844fe | |||
91f1797e86 | |||
df751e8390 | |||
645189643e | |||
bc529924c3 | |||
bc7f1d1120 | |||
a3977996e9 | |||
3df9ef465d | |||
454b3a9190 | |||
39360aeb23 | |||
a8993ba374 | |||
a50453260d | |||
2c04339ee2 | |||
7ca23a6cf6 | |||
4697dfedeb | |||
14f73a9c23 | |||
5d7c0f4d79 | |||
deed0a67a0 | |||
d2333f8ebb | |||
358768df9d | |||
9950fd97c5 | |||
ab4bdb0271 | |||
5ec0ac8874 | |||
b630fcb826 | |||
7dcd5c74c1 | |||
f2402ff813 | |||
e3a92f05c2 | |||
3736e7d858 | |||
f9adc703dc | |||
671f325f14 | |||
5df12ecbc2 | |||
2634cefe44 | |||
88a9c95a03 | |||
3c60ddec08 | |||
c1b9daea5b | |||
9baf420781 | |||
e95fd4b48f | |||
babbfc7221 | |||
eb409d4936 | |||
a9be8a0e35 | |||
e909b40f5c | |||
060672346e | |||
6abf8f9108 | |||
4321362cf8 | |||
09d51fd394 | |||
1e0a830c33 | |||
ccc22d8237 | |||
a6744f809c | |||
31dd61ffcf | |||
2edc808012 | |||
f1851ade02 | |||
65553627c8 | |||
f41d1df6d7 | |||
a8dac4007e | |||
9e186518c6 | |||
ac7a582c74 | |||
5bf058e323 | |||
67f4538b54 | |||
2e2934db95 | |||
e3100de700 | |||
0b300475d9 | |||
481e6824f3 | |||
eb13b52f45 | |||
9874368b78 | |||
ced7434c34 | |||
5ea6d39184 | |||
ca2bc23e8d | |||
32fe3e22c9 | |||
3e60f0b19b | |||
bf40f42476 | |||
4c3088b02a | |||
97312873b2 | |||
8031908a03 | |||
959e309ff2 | |||
172d2fc0ae | |||
5e2df33c54 | |||
50184579f5 | |||
d6bf226b2f | |||
796cccce30 | |||
61d7c48523 | |||
9e302d2924 | |||
5b5bbb2ebe | |||
32a5c605c6 | |||
78bcffd3e4 | |||
2a94da0c1d | |||
3335503ec0 | |||
e24018c77b | |||
2f6128ce26 | |||
e81b962f05 | |||
079792b89a | |||
fe6a721e36 | |||
f8b38b73bb | |||
e81f874c80 | |||
8ca4bcf4d1 | |||
1a959a2ace | |||
ce705121e9 | |||
9beb4a8ad0 | |||
77dd8cf056 | |||
296c2b6e5c | |||
90ee2871be | |||
0468622cc6 | |||
1499e7804c | |||
a5d665ce01 | |||
fc8c6a546e | |||
577d3d465f | |||
c99d3ef68f | |||
7930b8dbf7 | |||
f6f2eeb119 | |||
eaeed30931 | |||
9d0be98918 | |||
d845577eac | |||
b1ddc35006 | |||
7d760f1091 | |||
481b1ddfa1 | |||
75074a73d0 | |||
a8c69e5520 | |||
d40d0e770b | |||
e4ea6b83a6 | |||
4f120e3c23 | |||
5c81c0982f | |||
89b3eb3b53 | |||
6a96686263 | |||
7788ab94c8 | |||
5b30c29424 | |||
24a8bbfa66 | |||
2bd5b2ef93 | |||
b5dce1a2f0 | |||
4b6a883ed9 | |||
c9dcb46dc8 | |||
f4aa4ac70e | |||
70740cc973 | |||
7e9d5af03c | |||
a3328f0d7f | |||
fb357810cb | |||
30871db28e | |||
b4e77f1457 | |||
e3bde6844b | |||
ce7c41b9c4 | |||
a9be35d9ab | |||
7c0d8438b0 | |||
94c703c2d5 | |||
bda9f48034 | |||
789c49065c | |||
f51fdcfe2b | |||
a3c7d4247c | |||
7e4a6e9919 | |||
cfb12662f3 | |||
5bfcf3f0c1 | |||
7994594595 | |||
6cb7b1ab5e | |||
0f77021c94 | |||
4658dd7813 | |||
f49a36789f | |||
752256a703 | |||
1fa8edd360 | |||
257b503f8a | |||
f0f1f7f33e | |||
597779ee83 | |||
84730fa795 | |||
6b6942cdbe | |||
adfdee1ef7 | |||
a7a4e6dbed | |||
51ecdf3b86 | |||
a8e452df58 | |||
2da2dc4732 | |||
6165466253 | |||
e4458749e6 | |||
a45992e7de | |||
8ff3546b5d | |||
a7ce19c62e | |||
c46ebd12b1 | |||
33ab545711 | |||
b411d6f974 | |||
19187ae7be | |||
21e84f16eb | |||
cb9ecdcf11 | |||
0552c4510c | |||
6f4e1b45fb | |||
535fc1736a | |||
f2efd77482 | |||
b31ab42399 | |||
a2b23a3292 | |||
7c80298814 | |||
0495d2b0ff | |||
fd41bd923c | |||
1bce2a9193 | |||
f6f37533b1 | |||
1bef7668fc | |||
c5fef19d6a | |||
6ecc8bf8e7 | |||
14f2bde839 | |||
c8c644fd96 | |||
04ead8d3f3 | |||
9cc8c478b9 | |||
0a27b2bd28 | |||
3d044414a2 | |||
36f13cef14 | |||
79079c6a08 | |||
f8a3773911 | |||
469e775a97 | |||
2163cb1657 | |||
3e31bbd244 | |||
d4704811b9 | |||
1ba28c5bbf | |||
179ac20a83 | |||
8583203e26 | |||
6df33967bd | |||
1843c18959 | |||
df536787f0 | |||
006fadc53b | |||
4fda03d823 | |||
bda179b761 | |||
f0792d1179 | |||
8f64507c9c | |||
d9a9759a11 | |||
3024684bf1 | |||
79a5d9eba5 | |||
ef2f198bd3 | |||
04eae300bc | |||
d0aa4565cc | |||
6fac7d3f8c | |||
a47ce19ef2 | |||
72dc8a52e6 | |||
fdb35af2a8 | |||
0ef19c8e0b | |||
75d1e15eef | |||
761469af16 | |||
a2859d0359 | |||
ed4cc45b44 | |||
d7f2304e19 | |||
f40d668652 | |||
81f38f90c3 | |||
2a5d87d32e | |||
255faef838 | |||
8ae68c0652 | |||
e6fd62785f | |||
df54373ba8 | |||
fcc3d10ff1 | |||
20ae5d88ba | |||
b3225a0f11 | |||
f09ea6cd09 | |||
7d3ba345f3 | |||
a3f71751eb | |||
2051a1b67c | |||
0a3c4d0ed8 | |||
2608238acb | |||
e6938093ca | |||
86b2646ec6 | |||
7d08f48786 | |||
af654b2e51 | |||
796b4b6582 | |||
9effade48f | |||
44541dc0ef | |||
f68bec22d9 | |||
0e69148802 | |||
819145dca6 | |||
4b3ef8a97d | |||
24ee84feaf | |||
d3bb8b6279 | |||
219c53bb03 | |||
16b1ab75bd | |||
325e5130b7 | |||
bde069b75e | |||
f461eadb78 | |||
d32347137a | |||
71b771dc5d | |||
0d3b70571a | |||
bef7599068 | |||
3c11d93a29 | |||
29880358f0 | |||
7db2a76fd6 | |||
5c0f4f9103 | |||
3c85ef6e7a | |||
a2dcc00524 | |||
f793b7aa48 | |||
81d298f55c | |||
07034111d5 | |||
7acf5110db | |||
50f90ec045 | |||
1c71c1f0a5 | |||
eec96cae11 | |||
59c4b30d23 | |||
c551601a99 | |||
086c7c9eda | |||
2e628eb33d | |||
a3f55d9560 | |||
e89003a2e3 | |||
61a586e96a | |||
e6bce61e81 | |||
d1a87f1cbf | |||
5e49c8db0c | |||
daa7c7f044 | |||
d0f54e2bbd | |||
2189396c54 | |||
4268f5837b | |||
a43125dc18 | |||
35530a4de4 | |||
d1e24bf344 | |||
6e74af9d6c | |||
33f616c7dc | |||
c1d27a197b | |||
3de30e7848 | |||
e4505aab14 | |||
78f8879463 | |||
3755d3f251 | |||
ae5c145c3f | |||
07ddc128b4 | |||
674e50ba0d | |||
2f2ba72e92 | |||
0547b8b075 | |||
040ac16526 | |||
1c662f4330 | |||
765bb777e3 | |||
23beddc2b1 | |||
7b7a39291a | |||
21e5e780cc | |||
97928e7abe | |||
28add7d729 | |||
0823979d78 | |||
c7d4051054 | |||
8b41ad38d3 | |||
8c1235bdf1 | |||
dd26b1df3e | |||
02999e422e | |||
82b544c664 | |||
443b7ce63d | |||
eda4953c3d | |||
41b03831b3 | |||
da7f306dcb | |||
c8aa2a477e | |||
f5716a22aa | |||
185b1e1c3b | |||
c39400373d | |||
e04b83ff2c | |||
992ccf0054 | |||
cb6023e722 | |||
4af8e959b6 | |||
04679fe8bc | |||
7a3db717e0 | |||
38ffcbc1af | |||
d5c5284b1a | |||
bc7c912aa9 | |||
dbf56b5db8 | |||
127b852d7d | |||
cfb67acf6d | |||
f663cec583 | |||
e216ed4430 | |||
7c7f09da99 | |||
a616d6ea09 | |||
5e6c9b1fc0 | |||
44431beba4 | |||
1cef508aa3 | |||
21c05df2ba | |||
b11b8bf09c | |||
f94128417a | |||
d1c6d8777a | |||
1198fcc279 | |||
014e437944 | |||
1eb35d880f | |||
c5a9c0fc5c | |||
8ae9b96b33 | |||
871204438b | |||
cb1a2124a7 | |||
820f3ddd28 | |||
873183cc77 | |||
8741a38fe2 | |||
b273c3f088 | |||
578c85e416 | |||
804bf60609 | |||
75b8f85315 | |||
c28e1c0267 | |||
fe99f9d7d5 | |||
eb5eb51233 | |||
4d91e41bef | |||
7a90f3713d | |||
555737bcff | |||
5cf1b806b1 | |||
48cb642554 | |||
fe13c6dc18 | |||
b2a4f39401 | |||
259eba0c84 | |||
aa8912611f | |||
dbdc464dee | |||
640dc700a6 | |||
d0c6f905f6 | |||
295504eb45 | |||
cc78fdd0ef | |||
c0191c235d | |||
60d3b04030 | |||
2104d8f332 | |||
ec597e285d | |||
d61a0226b8 | |||
135754159e | |||
9e357544d1 | |||
3dac8b9e82 | |||
9fb39146b7 | |||
e256d74761 | |||
5cd43244e9 | |||
cff768e63c | |||
ad3dfff270 | |||
7ca6279850 | |||
44eddae9d0 | |||
95eddf7a24 | |||
889e495992 | |||
22e9be3663 | |||
11f3e13688 | |||
315d4fa8d8 | |||
7a3fe1fed2 | |||
00b6d1a6ca | |||
38875b19fb | |||
44c68a333a | |||
6d2d38e124 | |||
851e0eaad5 | |||
d5aacae9d2 | |||
58f6f7fedb | |||
9dbefba7cd | |||
991cb6e3d7 | |||
4330393c9b | |||
cd5572f250 | |||
776fe07932 | |||
36f3a4c757 | |||
86370c1ac5 | |||
bb50f33fec | |||
be276a58dc | |||
0d64196cf1 | |||
5e77733f1a | |||
851946dc9a | |||
e72e4cb599 | |||
40201dceb1 | |||
e3304f5a83 | |||
3c1176be43 | |||
012999a33b | |||
2a164310be | |||
9347140480 | |||
87c5b40454 | |||
9a30c0094e | |||
09c6e478e1 | |||
98c5414092 | |||
76753e8ca6 | |||
a10cebc033 | |||
5f6ea09570 | |||
2a115eccc3 | |||
2450cf4dd0 | |||
1835b6dd45 | |||
24829288bb | |||
624a9ae9e6 | |||
70aafb68d4 | |||
0c817666f5 | |||
99fe55c7df | |||
65f4c4f060 | |||
1071ae0455 | |||
3d5df51382 | |||
4abb13e6ca | |||
9c0603ea84 | |||
dd99c2c7e1 | |||
bff8947a8b | |||
678bc75719 | |||
86856f687a | |||
1eb4bf698a | |||
594af3f4d8 | |||
0f1bb00e62 | |||
01ce0fd9b1 | |||
099e31ea64 | |||
97b5aaf1c2 | |||
87c8048afb | |||
2d5005a24a | |||
263ca6e3b7 | |||
8f1f1db6f2 | |||
0a614a0e79 | |||
d27ca9bd0a | |||
6fcc9ec669 | |||
0a87bb5a02 | |||
f92ac03f8f | |||
4be7d82168 | |||
45fb40ee7f | |||
1cdbefdc9c | |||
fd409dcbd1 | |||
8a14f2c734 | |||
732095c59a | |||
d4d5a20eb1 | |||
e0aed6a035 | |||
19e5c7e9c9 | |||
ebd8951db4 | |||
4e6a1e3287 | |||
370ec68c76 | |||
8ee289c17c | |||
5fbca5f096 | |||
4c59f10469 | |||
18e6d08e93 | |||
784e731c77 | |||
09463eee6f | |||
ec4cc41102 | |||
d3c556bb5d | |||
86fac4e139 | |||
7f0a3b514f | |||
7cbef318e1 | |||
541ec13f70 | |||
8b5785532a | |||
858198e385 | |||
d47c2ec4c3 | |||
8ded561341 | |||
a8f9bfb98c | |||
1376328b0b | |||
dab1f90a2f | |||
ce600d6822 | |||
f376eaf316 | |||
a15f91f029 | |||
a6ee37ebef | |||
eb2331edb6 | |||
c5a6ac4b11 | |||
58dcf6b469 | |||
ce93f89531 | |||
6d37f59f97 | |||
9bd6121476 | |||
99cea18cc6 | |||
d798338426 | |||
3fc7e9c543 | |||
984b06f29c | |||
417635f58c | |||
aa5bccb403 | |||
b4d7a80343 | |||
e10eaa99f8 | |||
427b25d4b7 | |||
1781d4e7a5 | |||
0c519027d4 | |||
fec98dba7f | |||
613fa9aa92 | |||
fe7d9845bd | |||
23a0f0a2b4 | |||
031d96b369 | |||
1cd9cec988 | |||
89af12786a | |||
c92b576018 | |||
096f514b66 | |||
6cbaad13b1 | |||
c30c6c7f41 | |||
943d558ca8 | |||
53e10a59c1 | |||
8bb84f2edc | |||
a841eac968 | |||
1eac64966f | |||
2e7dd977c4 | |||
11e38a651e | |||
21fda4f75f | |||
3f3026ca05 | |||
66e690a277 | |||
87c1060ef5 | |||
ee741232d4 | |||
f0c5270f84 | |||
a7a40da0aa | |||
b4eab90b74 | |||
c839a96874 | |||
cf841b821b | |||
fd62b9f721 | |||
d12dde092f | |||
075d7ba884 | |||
4dc97cd730 | |||
6c7d4fb59a | |||
28b422f87f | |||
8e01a1c176 | |||
2af901862f | |||
5a2331afd4 | |||
be7fe42dcd | |||
86e61e9dc6 | |||
917d613465 | |||
9de9488b04 | |||
14d0942f5a | |||
af41c91d60 | |||
c7862ae2bd | |||
5e1c45cb84 | |||
0881edff66 | |||
048c42db23 | |||
3c1ad916e7 | |||
3bd8dd1732 | |||
8d2a3414c1 | |||
10307418dc | |||
8bef91a948 | |||
2110901fa0 | |||
aec4ce1248 | |||
2a242af5a8 | |||
3665fc17fb | |||
7887621c9b | |||
a5924fcba2 | |||
ebbb7354d6 | |||
bcf217f7be | |||
096da771dc | |||
a6ffd5258a | |||
ebebf5c1a8 | |||
e172b5e98d | |||
aeda134392 | |||
8747599780 | |||
4c34ef0a82 | |||
a16766e01a | |||
d9e9218445 | |||
de52e10486 | |||
d46930712e | |||
228bde3678 | |||
952be29e39 | |||
9e037c66b4 | |||
823d42ef9b | |||
00a1c77c65 | |||
c9ff2bc617 | |||
73764b7bcd | |||
bfb9839828 | |||
0ae1bb2655 | |||
ff570474b3 | |||
c90926c899 | |||
05f56189f1 | |||
9354e61414 | |||
e1a090b451 | |||
1a51946f5d | |||
4614f589ec | |||
a2ceb138bb | |||
5b58e62176 | |||
e3ba2d3153 | |||
4067a7858d | |||
fbbc4ff73a | |||
1bc9d34209 | |||
c700a335cc | |||
b7cc898a6a | |||
fd9d3fd9e1 | |||
88f0a1d9e1 | |||
71b030cf63 | |||
0735a68bc9 | |||
7bc6c9d9a0 | |||
38aa0acb0d | |||
fb72c855ee | |||
3e2d511c6b | |||
bbb448d3be | |||
88a0452f26 | |||
0392f638ae | |||
5cb2ded45c | |||
b9c64a1057 | |||
354c802c22 | |||
c117dfdc24 | |||
2c41ea320f | |||
fcd2655a4a | |||
e4a828a658 | |||
c18739f262 | |||
65d2fd668b | |||
e3fd0d2671 | |||
e85f3236f4 | |||
2e796fe70e | |||
75e5a7eeff | |||
7c6a8bd33d | |||
3881a5a214 | |||
85dfc8b80c | |||
6eb4df3bff | |||
7af661be97 | |||
adaf03bbc5 | |||
1d5b343e5b | |||
efbd8e4156 | |||
9ac3fdeb96 | |||
0c4b373319 | |||
5770d110d0 | |||
4384f0d468 | |||
37fde650a5 | |||
285f7a1c75 | |||
35c39173bc | |||
91e1a92cdd | |||
7d7007c6e3 | |||
9b3b574760 | |||
3420cdbe85 | |||
dd72560ce2 | |||
595d4cd678 | |||
8401264952 | |||
ea38a91202 | |||
f3888ff449 | |||
6d2472da5f | |||
8b6dd34148 | |||
7ccb69a920 | |||
5f4219ca84 | |||
f88b33b047 | |||
26a8308c72 | |||
59380b26ed | |||
e85635e6f9 | |||
e6a965f767 | |||
c39c65dfce | |||
aa8d1801de | |||
80a641546a | |||
2af7be3791 | |||
deb2aa1dc1 | |||
3e7996d371 | |||
c1f421273b | |||
44f8b5b8a6 | |||
5830c8dbfc | |||
e2a31f2a92 | |||
fb9da5f885 | |||
adf980425c | |||
f56f6889bc | |||
3e301996c9 | |||
8ab50ac930 | |||
ec09c8d37b | |||
f38c70a6c8 | |||
2461c246fb | |||
b45568ba96 | |||
0e424f7105 | |||
e02e370d4e | |||
5fa44b9f6d | |||
b504737c19 | |||
3158b6706d | |||
2363839e94 | |||
04bcb27275 | |||
46faa66642 | |||
fa6c758004 | |||
d2dfc2d634 | |||
96c36de45b | |||
7b7307761c | |||
9531d78820 | |||
db8c8979fd | |||
d7ed4c32cf | |||
64be02e6b7 | |||
30f483e769 | |||
eb3c71bafa | |||
3c9d679a53 | |||
6f7e2e9582 | |||
91c51977af | |||
8075f0696f | |||
5e6111e107 | |||
e9dcc1e2fe | |||
bb1a101d38 | |||
28e8d2a8e0 | |||
b64292975a | |||
bc7c289512 | |||
9df3022c4b | |||
aa5ef0b9ac |
13
.github/FUNDING.yml
vendored
Normal file
13
.github/FUNDING.yml
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
# These are supported funding model platforms
|
||||
|
||||
github: [halfrost]
|
||||
patreon: # Replace with a single Patreon username
|
||||
open_collective: # Replace with a single Open Collective username
|
||||
ko_fi: # Replace with a single Ko-fi username
|
||||
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
|
||||
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
|
||||
liberapay: # Replace with a single Liberapay username
|
||||
issuehunt: # Replace with a single IssueHunt username
|
||||
otechie: # Replace with a single Otechie username
|
||||
lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
|
||||
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
|
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
*.toml
|
||||
.idea
|
14
.vscode/settings.json
vendored
Normal file
14
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
{
|
||||
"go.formatTool": "gofmt",
|
||||
"go.formatFlags": [
|
||||
"-s"
|
||||
],
|
||||
"go.autocompleteUnimportedPackages": true,
|
||||
"[go]": {
|
||||
"editor.insertSpaces": false,
|
||||
"editor.formatOnSave": true,
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.organizeImports": true
|
||||
}
|
||||
}
|
||||
}
|
1173
README_old.md
Normal file
1173
README_old.md
Normal file
File diff suppressed because it is too large
Load Diff
20
ctl/README.md
Normal file
20
ctl/README.md
Normal file
@ -0,0 +1,20 @@
|
||||
# LeetCode-Go ctl
|
||||
|
||||
## 配置方法
|
||||
|
||||
1. 在`.gitignore`中,添加一行`*.toml`
|
||||
2. 在`LeetCode-Go`目录下,添加文本文件`config.toml`。
|
||||
3. 把以下内容复制到`config.toml`中。
|
||||
4. 把`config.toml`中的`test`分别修改为你的 leetcode `用户名`和`密码`。
|
||||
5. 去 leetcode 登录后,把网站 cookie 复制 (需要复制 csrftoken 和 LEETCODE_SESSION) 并替换 `config.toml`中的`Cookie`。
|
||||
|
||||
```toml
|
||||
Username="test"
|
||||
Password="test"
|
||||
Cookie="csrftoken=XXXXXXXXX; LEETCODE_SESSION=YYYYYYYY;"
|
||||
CSRFtoken="ZZZZZZZZ"
|
||||
```
|
||||
|
||||
## PDF 生成
|
||||
|
||||
用 `leetcode-go pdf` 命令先生成书籍内容的合并版本 pdf.md,再用 vscode 或者其他支持 toc 目录生成的工具,生成 toc。最后用 Typora 把 md 文件转换成 pdf。就可以发布 release 新版本了。
|
30
ctl/command.go
Normal file
30
ctl/command.go
Normal file
@ -0,0 +1,30 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var rootCmd = &cobra.Command{
|
||||
Use: "leetcode-go",
|
||||
Short: "A simple command line client for leetcode-go.",
|
||||
}
|
||||
|
||||
func execute() {
|
||||
if err := rootCmd.Execute(); err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(-1)
|
||||
}
|
||||
}
|
||||
|
||||
func init() {
|
||||
rootCmd.AddCommand(
|
||||
versionCmd,
|
||||
newBuildCommand(),
|
||||
newLabelCommand(),
|
||||
newPDFCommand(),
|
||||
newRefresh(),
|
||||
)
|
||||
}
|
32
ctl/config.go
Normal file
32
ctl/config.go
Normal file
@ -0,0 +1,32 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"github.com/BurntSushi/toml"
|
||||
)
|
||||
|
||||
const (
|
||||
configTOML = "config.toml"
|
||||
)
|
||||
|
||||
type config struct {
|
||||
Username string
|
||||
Password string
|
||||
Cookie string
|
||||
CSRFtoken string
|
||||
}
|
||||
|
||||
func (c config) String() string {
|
||||
return fmt.Sprintf("Username: %s, Password: %s", c.Username, c.Password)
|
||||
}
|
||||
|
||||
func getConfig() *config {
|
||||
cfg := new(config)
|
||||
if _, err := toml.DecodeFile(configTOML, &cfg); err != nil {
|
||||
log.Panicf(err.Error())
|
||||
}
|
||||
// log.Printf("get config: %s", cfg)
|
||||
return cfg
|
||||
}
|
21
ctl/error.go
Normal file
21
ctl/error.go
Normal file
@ -0,0 +1,21 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
)
|
||||
|
||||
const (
|
||||
// ExitSuccess define
|
||||
ExitSuccess = iota
|
||||
// ExitError define
|
||||
ExitError
|
||||
// ExitBadArgs define
|
||||
ExitBadArgs
|
||||
)
|
||||
|
||||
// ExitWithError define
|
||||
func ExitWithError(code int, err error) {
|
||||
fmt.Fprintln(os.Stderr, "Error: ", err)
|
||||
os.Exit(code)
|
||||
}
|
347
ctl/label.go
Normal file
347
ctl/label.go
Normal file
@ -0,0 +1,347 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var (
|
||||
chapterOneFileOrder = []string{"_index", "Data_Structure", "Algorithm", "Time_Complexity"}
|
||||
chapterOneMenuOrder = []string{"_index", "#关于作者", "Data_Structure", "Algorithm", "Time_Complexity"}
|
||||
chapterTwoFileOrder = []string{"_index", "Array", "String", "Two_Pointers", "Linked_List", "Stack", "Tree", "Dynamic_Programming", "Backtracking", "Depth_First_Search", "Breadth_First_Search",
|
||||
"Binary_Search", "Math", "Hash_Table", "Sorting", "Bit_Manipulation", "Union_Find", "Sliding_Window", "Segment_Tree", "Binary_Indexed_Tree"}
|
||||
chapterThreeFileOrder = []string{"_index", "Segment_Tree", "UnionFind", "LRUCache", "LFUCache"}
|
||||
preNextHeader = "----------------------------------------------\n<div style=\"display: flex;justify-content: space-between;align-items: center;\">\n"
|
||||
preNextFotter = "</div>"
|
||||
delLine = "----------------------------------------------\n"
|
||||
delHeader = "<div style=\"display: flex;justify-content: space-between;align-items: center;\">"
|
||||
delLabel = "<[a-zA-Z]+.*?>([\\s\\S]*?)</[a-zA-Z]*?>"
|
||||
delFooter = "</div>"
|
||||
|
||||
//ErrNoFilename is thrown when the path the the file to tail was not given
|
||||
ErrNoFilename = errors.New("You must provide the path to a file in the \"-file\" flag.")
|
||||
|
||||
//ErrInvalidLineCount is thrown when the user provided 0 (zero) as the value for number of lines to tail
|
||||
ErrInvalidLineCount = errors.New("You cannot tail zero lines.")
|
||||
|
||||
chapterMap = map[string]map[string]string{
|
||||
"ChapterOne": {
|
||||
"_index": "第一章 序章",
|
||||
"Data_Structure": "1.1 数据结构知识",
|
||||
"Algorithm": "1.2 算法知识",
|
||||
"Time_Complexity": "1.3 时间复杂度",
|
||||
},
|
||||
"ChapterTwo": {
|
||||
"_index": "第二章 算法专题",
|
||||
"Array": "2.01 Array",
|
||||
"String": "2.02 String",
|
||||
"Two_Pointers": "2.03 ✅ Two Pointers",
|
||||
"Linked_List": "2.04 ✅ Linked List",
|
||||
"Stack": "2.05 ✅ Stack",
|
||||
"Tree": "2.06 Tree",
|
||||
"Dynamic_Programming": "2.07 Dynamic Programming",
|
||||
"Backtracking": "2.08 ✅ Backtracking",
|
||||
"Depth_First_Search": "2.09 Depth First Search",
|
||||
"Breadth_First_Search": "2.10 Breadth First Search",
|
||||
"Binary_Search": "2.11 Binary Search",
|
||||
"Math": "2.12 Math",
|
||||
"Hash_Table": "2.13 Hash Table",
|
||||
"Sorting": "2.14 ✅ Sorting",
|
||||
"Bit_Manipulation": "2.15 ✅ Bit Manipulation",
|
||||
"Union_Find": "2.16 ✅ Union Find",
|
||||
"Sliding_Window": "2.17 ✅ Sliding Window",
|
||||
"Segment_Tree": "2.18 ✅ Segment Tree",
|
||||
"Binary_Indexed_Tree": "2.19 ✅ Binary Indexed Tree",
|
||||
},
|
||||
"ChapterThree": {
|
||||
"_index": "第三章 一些模板",
|
||||
"Segment_Tree": "3.1 Segment Tree",
|
||||
"UnionFind": "3.2 UnionFind",
|
||||
"LRUCache": "3.3 LRUCache",
|
||||
"LFUCache": "3.4 LFUCache",
|
||||
},
|
||||
"ChapterFour": {
|
||||
"_index": "第四章 Leetcode 题解",
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
func getChapterFourFileOrder() ([]string, []int) {
|
||||
solutions, solutionIds := LoadChapterFourDir()
|
||||
chapterFourFileOrder := []string{"_index"}
|
||||
chapterFourFileOrder = append(chapterFourFileOrder, solutions...)
|
||||
fmt.Printf("ChapterFour 中包括 _index 有 %v 个文件, len(id) = %v\n", len(chapterFourFileOrder), len(solutionIds))
|
||||
return chapterFourFileOrder, solutionIds
|
||||
}
|
||||
|
||||
func newLabelCommand() *cobra.Command {
|
||||
mc := &cobra.Command{
|
||||
Use: "label <subcommand>",
|
||||
Short: "Label related commands",
|
||||
}
|
||||
//mc.PersistentFlags().StringVar(&logicEndpoint, "endpoint", "localhost:5880", "endpoint of logic service")
|
||||
mc.AddCommand(
|
||||
newAddPreNext(),
|
||||
newDeletePreNext(),
|
||||
)
|
||||
return mc
|
||||
}
|
||||
|
||||
func newAddPreNext() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "add-pre-next",
|
||||
Short: "Add pre-next label",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
addPreNext()
|
||||
},
|
||||
}
|
||||
// cmd.Flags().StringVar(&alias, "alias", "", "alias")
|
||||
// cmd.Flags().StringVar(&appId, "appid", "", "appid")
|
||||
return cmd
|
||||
}
|
||||
|
||||
func newDeletePreNext() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "del-pre-next",
|
||||
Short: "Delete pre-next label",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
delPreNext()
|
||||
},
|
||||
}
|
||||
// cmd.Flags().StringVar(&alias, "alias", "", "alias")
|
||||
// cmd.Flags().StringVar(&appId, "appid", "", "appid")
|
||||
return cmd
|
||||
}
|
||||
|
||||
func addPreNext() {
|
||||
// Chpater one add pre-next
|
||||
addPreNextLabel(chapterOneFileOrder, []string{}, []int{}, "", "ChapterOne", "ChapterTwo")
|
||||
// Chpater two add pre-next
|
||||
addPreNextLabel(chapterTwoFileOrder, chapterOneFileOrder, []int{}, "ChapterOne", "ChapterTwo", "ChapterThree")
|
||||
// Chpater three add pre-next
|
||||
addPreNextLabel(chapterThreeFileOrder, chapterTwoFileOrder, []int{}, "ChapterTwo", "ChapterThree", "ChapterFour")
|
||||
// Chpater four add pre-next
|
||||
//fmt.Printf("%v\n", getChapterFourFileOrder())
|
||||
chapterFourFileOrder, solutionIds := getChapterFourFileOrder()
|
||||
addPreNextLabel(chapterFourFileOrder, chapterThreeFileOrder, solutionIds, "ChapterThree", "ChapterFour", "")
|
||||
}
|
||||
|
||||
func addPreNextLabel(order, preOrder []string, chapterFourIds []int, preChapter, chapter, nextChapter string) {
|
||||
var (
|
||||
exist bool
|
||||
err error
|
||||
res []byte
|
||||
count int
|
||||
)
|
||||
for index, path := range order {
|
||||
tmp := ""
|
||||
if index == 0 {
|
||||
if chapter == "ChapterOne" {
|
||||
// 第一页不需要“上一章”
|
||||
tmp = "\n\n" + delLine + fmt.Sprintf("<p align = \"right\"><a href=\"https://books.halfrost.com/leetcode/%v/%v/\">下一页➡️</a></p>\n", chapter, order[index+1])
|
||||
} else {
|
||||
if chapter == "ChapterFour" {
|
||||
tmp = "\n\n" + preNextHeader + fmt.Sprintf("<p><a href=\"https://books.halfrost.com/leetcode/%v/%v/\">⬅️上一章</a></p>\n", preChapter, preOrder[len(preOrder)-1]) + fmt.Sprintf("<p><a href=\"https://books.halfrost.com/leetcode/%v/%v/%v/\">下一页➡️</a></p>\n", chapter, GetChpaterFourFileNum(chapterFourIds[(index-1)+1]), order[index+1]) + preNextFotter
|
||||
} else {
|
||||
tmp = "\n\n" + preNextHeader + fmt.Sprintf("<p><a href=\"https://books.halfrost.com/leetcode/%v/%v/\">⬅️上一章</a></p>\n", preChapter, preOrder[len(preOrder)-1]) + fmt.Sprintf("<p><a href=\"https://books.halfrost.com/leetcode/%v/%v/\">下一页➡️</a></p>\n", chapter, order[index+1]) + preNextFotter
|
||||
}
|
||||
}
|
||||
} else if index == len(order)-1 {
|
||||
if chapter == "ChapterFour" {
|
||||
// 最后一页不需要“下一页”
|
||||
tmp = "\n\n" + delLine + fmt.Sprintf("<p><a href=\"https://books.halfrost.com/leetcode/%v/%v/%v/\">⬅️上一页</a></p>\n", chapter, GetChpaterFourFileNum(chapterFourIds[(index-1)-1]), order[index-1])
|
||||
} else {
|
||||
tmp = "\n\n" + preNextHeader + fmt.Sprintf("<p><a href=\"https://books.halfrost.com/leetcode/%v/%v/\">⬅️上一页</a></p>\n", chapter, order[index-1]) + fmt.Sprintf("<p><a href=\"https://books.halfrost.com/leetcode/%v/\">下一章➡️</a></p>\n", nextChapter) + preNextFotter
|
||||
}
|
||||
} else if index == 1 {
|
||||
if chapter == "ChapterFour" {
|
||||
tmp = "\n\n" + preNextHeader + fmt.Sprintf("<p><a href=\"https://books.halfrost.com/leetcode/%v/\">⬅️上一页</a></p>\n", chapter) + fmt.Sprintf("<p><a href=\"https://books.halfrost.com/leetcode/%v/%v/%v/\">下一页➡️</a></p>\n", chapter, GetChpaterFourFileNum(chapterFourIds[(index-1)+1]), order[index+1]) + preNextFotter
|
||||
} else {
|
||||
tmp = "\n\n" + preNextHeader + fmt.Sprintf("<p><a href=\"https://books.halfrost.com/leetcode/%v/\">⬅️上一页</a></p>\n", chapter) + fmt.Sprintf("<p><a href=\"https://books.halfrost.com/leetcode/%v/%v/\">下一页➡️</a></p>\n", chapter, order[index+1]) + preNextFotter
|
||||
}
|
||||
} else {
|
||||
if chapter == "ChapterFour" {
|
||||
tmp = "\n\n" + preNextHeader + fmt.Sprintf("<p><a href=\"https://books.halfrost.com/leetcode/%v/%v/%v/\">⬅️上一页</a></p>\n", chapter, GetChpaterFourFileNum(chapterFourIds[(index-1)-1]), order[index-1]) + fmt.Sprintf("<p><a href=\"https://books.halfrost.com/leetcode/%v/%v/%v/\">下一页➡️</a></p>\n", chapter, GetChpaterFourFileNum(chapterFourIds[(index-1)+1]), order[index+1]) + preNextFotter
|
||||
} else {
|
||||
tmp = "\n\n" + preNextHeader + fmt.Sprintf("<p><a href=\"https://books.halfrost.com/leetcode/%v/%v/\">⬅️上一页</a></p>\n", chapter, order[index-1]) + fmt.Sprintf("<p><a href=\"https://books.halfrost.com/leetcode/%v/%v/\">下一页➡️</a></p>\n", chapter, order[index+1]) + preNextFotter
|
||||
}
|
||||
}
|
||||
|
||||
if chapter == "ChapterFour" && index > 0 {
|
||||
path = fmt.Sprintf("%v/%v", GetChpaterFourFileNum(chapterFourIds[(index-1)]), path)
|
||||
}
|
||||
|
||||
exist, err = needAdd(fmt.Sprintf("../website/content/%v/%v.md", chapter, path))
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
// 当前没有上一页和下一页,才添加
|
||||
if !exist && err == nil {
|
||||
res, err = eofAdd(fmt.Sprintf("../website/content/%v/%v.md", chapter, path), tmp)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
WriteFile(fmt.Sprintf("../website/content/%v/%v.md", chapter, path), res)
|
||||
count++
|
||||
}
|
||||
}
|
||||
fmt.Printf("添加了 %v 个文件的 pre-next\n", count)
|
||||
}
|
||||
|
||||
func eofAdd(filePath string, labelString string) ([]byte, error) {
|
||||
f, err := os.OpenFile(filePath, os.O_RDONLY, 0644)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer f.Close()
|
||||
reader, output := bufio.NewReader(f), []byte{}
|
||||
|
||||
for {
|
||||
line, _, err := reader.ReadLine()
|
||||
if err != nil {
|
||||
if err == io.EOF {
|
||||
output = append(output, []byte(labelString)...)
|
||||
output = append(output, []byte("\n")...)
|
||||
return output, nil
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
output = append(output, line...)
|
||||
output = append(output, []byte("\n")...)
|
||||
}
|
||||
}
|
||||
|
||||
func delPreNext() {
|
||||
// Chpater one del pre-next
|
||||
delPreNextLabel(chapterOneFileOrder, []int{}, "ChapterOne")
|
||||
// Chpater two del pre-next
|
||||
delPreNextLabel(chapterTwoFileOrder, []int{}, "ChapterTwo")
|
||||
// Chpater three del pre-next
|
||||
delPreNextLabel(chapterThreeFileOrder, []int{}, "ChapterThree")
|
||||
// Chpater four del pre-next
|
||||
chapterFourFileOrder, solutionIds := getChapterFourFileOrder()
|
||||
delPreNextLabel(chapterFourFileOrder, solutionIds, "ChapterFour")
|
||||
}
|
||||
|
||||
func delPreNextLabel(order []string, chapterFourIds []int, chapter string) {
|
||||
count := 0
|
||||
for index, path := range order {
|
||||
lineNum := 5
|
||||
if index == 0 && chapter == "ChapterOne" || index == len(order)-1 && chapter == "ChapterFour" {
|
||||
lineNum = 3
|
||||
}
|
||||
if chapter == "ChapterFour" && index > 0 {
|
||||
path = fmt.Sprintf("%v/%v", GetChpaterFourFileNum(chapterFourIds[(index-1)]), path)
|
||||
}
|
||||
|
||||
exist, err := needAdd(fmt.Sprintf("../website/content/%v/%v.md", chapter, path))
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
// 存在才删除
|
||||
if exist && err == nil {
|
||||
removeLine(fmt.Sprintf("../website/content/%v/%v.md", chapter, path), lineNum+1)
|
||||
count++
|
||||
}
|
||||
}
|
||||
fmt.Printf("删除了 %v 个文件的 pre-next\n", count)
|
||||
// 另外一种删除方法
|
||||
// res, err := eofDel(fmt.Sprintf("../website/content/ChapterOne/%v.md", v))
|
||||
// if err != nil {
|
||||
// fmt.Println(err)
|
||||
// return
|
||||
// }
|
||||
// WriteFile(fmt.Sprintf("../website/content/ChapterOne/%v.md", v), res)
|
||||
}
|
||||
|
||||
func needAdd(filePath string) (bool, error) {
|
||||
f, err := os.OpenFile(filePath, os.O_RDONLY, 0644)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
defer f.Close()
|
||||
reader, output := bufio.NewReader(f), []byte{}
|
||||
for {
|
||||
line, _, err := reader.ReadLine()
|
||||
if err != nil {
|
||||
if err == io.EOF {
|
||||
return false, nil
|
||||
}
|
||||
return false, err
|
||||
}
|
||||
if ok, _ := regexp.Match(delHeader, line); ok {
|
||||
return true, nil
|
||||
} else if ok, _ := regexp.Match(delLabel, line); ok {
|
||||
return true, nil
|
||||
} else {
|
||||
output = append(output, line...)
|
||||
output = append(output, []byte("\n")...)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func eofDel(filePath string) ([]byte, error) {
|
||||
f, err := os.OpenFile(filePath, os.O_RDONLY, 0644)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer f.Close()
|
||||
reader, output := bufio.NewReader(f), []byte{}
|
||||
for {
|
||||
line, _, err := reader.ReadLine()
|
||||
if err != nil {
|
||||
if err == io.EOF {
|
||||
return output, nil
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
if ok, _ := regexp.Match(delLine, line); ok {
|
||||
reg := regexp.MustCompile(delLine)
|
||||
newByte := reg.ReplaceAll(line, []byte(""))
|
||||
output = append(output, newByte...)
|
||||
output = append(output, []byte("\n")...)
|
||||
} else if ok, _ := regexp.Match(delHeader, line); ok {
|
||||
reg := regexp.MustCompile(delHeader)
|
||||
newByte := reg.ReplaceAll(line, []byte(""))
|
||||
output = append(output, newByte...)
|
||||
output = append(output, []byte("\n")...)
|
||||
} else if ok, _ := regexp.Match(delLabel, line); ok {
|
||||
reg := regexp.MustCompile(delLabel)
|
||||
newByte := reg.ReplaceAll(line, []byte(""))
|
||||
output = append(output, newByte...)
|
||||
output = append(output, []byte("\n")...)
|
||||
} else if ok, _ := regexp.Match(delFooter, line); ok {
|
||||
reg := regexp.MustCompile(delFooter)
|
||||
newByte := reg.ReplaceAll(line, []byte(""))
|
||||
output = append(output, newByte...)
|
||||
output = append(output, []byte("\n")...)
|
||||
} else {
|
||||
output = append(output, line...)
|
||||
output = append(output, []byte("\n")...)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func removeLine(path string, lineNumber int) {
|
||||
file, err := ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
info, _ := os.Stat(path)
|
||||
mode := info.Mode()
|
||||
array := strings.Split(string(file), "\n")
|
||||
array = array[:len(array)-lineNumber-1]
|
||||
ioutil.WriteFile(path, []byte(strings.Join(array, "\n")), mode)
|
||||
//fmt.Println("remove line successful")
|
||||
}
|
104
ctl/lcproblems.go
Normal file
104
ctl/lcproblems.go
Normal file
@ -0,0 +1,104 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// LeetCodeProblemAll define
|
||||
type LeetCodeProblemAll struct {
|
||||
UserName string `json:"user_name"`
|
||||
NumSolved int32 `json:"num_solved"`
|
||||
NumTotal int32 `json:"num_total"`
|
||||
AcEasy int32 `json:"ac_easy"`
|
||||
AcMedium int32 `json:"ac_medium"`
|
||||
AcHard int32 `json:"ac_hard"`
|
||||
StatStatusPairs []StatStatusPairs `json:"stat_status_pairs"`
|
||||
FrequencyHigh float64 `json:"frequency_high"`
|
||||
FrequencyMid float64 `json:"frequency_mid"`
|
||||
CategorySlug string `json:"category_slug"`
|
||||
AcEasyTotal int32
|
||||
AcMediumTotal int32
|
||||
AcHardTotal int32
|
||||
}
|
||||
|
||||
// ConvertUserInfoModel define
|
||||
func ConvertUserInfoModel(lpa LeetCodeProblemAll) UserInfo {
|
||||
info := UserInfo{}
|
||||
info.UserName = lpa.UserName
|
||||
info.NumSolved = lpa.NumSolved
|
||||
info.NumTotal = lpa.NumTotal
|
||||
info.AcEasy = lpa.AcEasy
|
||||
info.AcMedium = lpa.AcMedium
|
||||
info.AcHard = lpa.AcHard
|
||||
info.FrequencyHigh = lpa.FrequencyHigh
|
||||
info.FrequencyMid = lpa.FrequencyMid
|
||||
info.CategorySlug = lpa.CategorySlug
|
||||
return info
|
||||
}
|
||||
|
||||
// StatStatusPairs define
|
||||
type StatStatusPairs struct {
|
||||
Stat Stat `json:"stat"`
|
||||
Status string `json:"status"`
|
||||
Difficulty Difficulty `json:"difficulty"`
|
||||
PaidOnly bool `json:"paid_only"`
|
||||
IsFavor bool `json:"is_favor"`
|
||||
Frequency float64 `json:"frequency"`
|
||||
Progress float64 `json:"progress"`
|
||||
}
|
||||
|
||||
// ConvertMdModelFromSsp define
|
||||
func ConvertMdModelFromSsp(problems []StatStatusPairs) []Mdrow {
|
||||
mdrows := []Mdrow{}
|
||||
for _, problem := range problems {
|
||||
res := Mdrow{}
|
||||
res.FrontendQuestionID = problem.Stat.FrontendQuestionID
|
||||
res.QuestionTitle = strings.TrimSpace(problem.Stat.QuestionTitle)
|
||||
res.QuestionTitleSlug = strings.TrimSpace(problem.Stat.QuestionTitleSlug)
|
||||
res.Acceptance = fmt.Sprintf("%.1f%%", (problem.Stat.TotalAcs/problem.Stat.TotalSubmitted)*100)
|
||||
res.Difficulty = DifficultyMap[problem.Difficulty.Level]
|
||||
res.Frequency = fmt.Sprintf("%f", problem.Frequency)
|
||||
mdrows = append(mdrows, res)
|
||||
}
|
||||
return mdrows
|
||||
}
|
||||
|
||||
// ConvertMdModelFromIds define
|
||||
func ConvertMdModelFromIds(problemsMap map[int]StatStatusPairs, ids []int) []Mdrow {
|
||||
mdrows := []Mdrow{}
|
||||
for _, v := range ids {
|
||||
res, problem := Mdrow{}, problemsMap[v]
|
||||
res.FrontendQuestionID = problem.Stat.FrontendQuestionID
|
||||
res.QuestionTitle = strings.TrimSpace(problem.Stat.QuestionTitle)
|
||||
res.QuestionTitleSlug = strings.TrimSpace(problem.Stat.QuestionTitleSlug)
|
||||
res.Acceptance = fmt.Sprintf("%.1f%%", (problem.Stat.TotalAcs/problem.Stat.TotalSubmitted)*100)
|
||||
res.Difficulty = DifficultyMap[problem.Difficulty.Level]
|
||||
res.Frequency = fmt.Sprintf("%f", problem.Frequency)
|
||||
mdrows = append(mdrows, res)
|
||||
}
|
||||
return mdrows
|
||||
}
|
||||
|
||||
// Stat define
|
||||
type Stat struct {
|
||||
QuestionTitle string `json:"question__title"`
|
||||
QuestionTitleSlug string `json:"question__title_slug"`
|
||||
TotalAcs float64 `json:"total_acs"`
|
||||
TotalSubmitted float64 `json:"total_submitted"`
|
||||
Acceptance string
|
||||
Difficulty string
|
||||
FrontendQuestionID int32 `json:"frontend_question_id"`
|
||||
}
|
||||
|
||||
// Difficulty define
|
||||
type Difficulty struct {
|
||||
Level int32 `json:"level"`
|
||||
}
|
||||
|
||||
// DifficultyMap define
|
||||
var DifficultyMap = map[int32]string{
|
||||
1: "Easy",
|
||||
2: "Medium",
|
||||
3: "Hard",
|
||||
}
|
5
ctl/main.go
Normal file
5
ctl/main.go
Normal file
@ -0,0 +1,5 @@
|
||||
package main
|
||||
|
||||
func main() {
|
||||
execute()
|
||||
}
|
90
ctl/mdrow.go
Normal file
90
ctl/mdrow.go
Normal file
@ -0,0 +1,90 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Mdrow define
|
||||
type Mdrow struct {
|
||||
FrontendQuestionID int32 `json:"question_id"`
|
||||
QuestionTitle string `json:"question__title"`
|
||||
QuestionTitleSlug string `json:"question__title_slug"`
|
||||
SolutionPath string `json:"solution_path"`
|
||||
Acceptance string `json:"acceptance"`
|
||||
Difficulty string `json:"difficulty"`
|
||||
Frequency string `json:"frequency"`
|
||||
}
|
||||
|
||||
// GenerateMdRows define
|
||||
func GenerateMdRows(solutionIds []int, mdrows []Mdrow) {
|
||||
mdMap := map[int]Mdrow{}
|
||||
for _, row := range mdrows {
|
||||
mdMap[int(row.FrontendQuestionID)] = row
|
||||
}
|
||||
for i := 0; i < len(solutionIds); i++ {
|
||||
if row, ok := mdMap[solutionIds[i]]; ok {
|
||||
s7 := standardizedTitle(row.QuestionTitle, row.FrontendQuestionID)
|
||||
mdMap[solutionIds[i]] = Mdrow{
|
||||
FrontendQuestionID: row.FrontendQuestionID,
|
||||
QuestionTitle: strings.TrimSpace(row.QuestionTitle),
|
||||
QuestionTitleSlug: row.QuestionTitleSlug,
|
||||
SolutionPath: fmt.Sprintf("[Go](https://github.com/halfrost/leetcode-go/tree/master/leetcode/%v)", fmt.Sprintf("%04d.%v", solutionIds[i], s7)),
|
||||
Acceptance: row.Acceptance,
|
||||
Difficulty: row.Difficulty,
|
||||
Frequency: row.Frequency,
|
||||
}
|
||||
} else {
|
||||
fmt.Printf("序号不存在 len(solutionIds) = %v len(mdrows) = %v len(solutionIds) = %v solutionIds[i] = %v QuestionTitle = %v\n", len(solutionIds), len(mdrows), len(solutionIds), solutionIds[i], mdrows[solutionIds[i]-1].QuestionTitle)
|
||||
}
|
||||
}
|
||||
for i := range mdrows {
|
||||
mdrows[i] = Mdrow{
|
||||
FrontendQuestionID: mdrows[i].FrontendQuestionID,
|
||||
QuestionTitle: strings.TrimSpace(mdrows[i].QuestionTitle),
|
||||
QuestionTitleSlug: mdrows[i].QuestionTitleSlug,
|
||||
SolutionPath: mdMap[int(mdrows[i].FrontendQuestionID)].SolutionPath,
|
||||
Acceptance: mdrows[i].Acceptance,
|
||||
Difficulty: mdrows[i].Difficulty,
|
||||
Frequency: mdrows[i].Frequency,
|
||||
}
|
||||
}
|
||||
// fmt.Printf("mdrows = %v\n\n", mdrows)
|
||||
}
|
||||
|
||||
// | 0001 | Two Sum | [Go](https://github.com/halfrost/leetcode-go/tree/master/leetcode/0001.Two-Sum)| 45.6% | Easy | |
|
||||
func (m Mdrow) tableLine() string {
|
||||
return fmt.Sprintf("|%04d|%v|%v|%v|%v||\n", m.FrontendQuestionID, m.QuestionTitle, m.SolutionPath, m.Acceptance, m.Difficulty)
|
||||
}
|
||||
|
||||
// SortByQuestionID define
|
||||
type SortByQuestionID []Mdrow
|
||||
|
||||
func (a SortByQuestionID) Len() int { return len(a) }
|
||||
func (a SortByQuestionID) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
|
||||
func (a SortByQuestionID) Less(i, j int) bool {
|
||||
return a[i].FrontendQuestionID < a[j].FrontendQuestionID
|
||||
}
|
||||
|
||||
// Mdrows define
|
||||
type Mdrows struct {
|
||||
Mdrows []Mdrow
|
||||
}
|
||||
|
||||
// | No. | Title | Solution | Acceptance | Difficulty | Frequency |
|
||||
// |:--------:|:--------------------------------------------------------------|:--------:|:--------:|:--------:|:--------:|
|
||||
func (mds Mdrows) table() string {
|
||||
res := "| No. | Title | Solution | Acceptance | Difficulty | Frequency |\n"
|
||||
res += "|:--------:|:--------------------------------------------------------------|:--------:|:--------:|:--------:|:--------:|\n"
|
||||
for _, p := range mds.Mdrows {
|
||||
res += p.tableLine()
|
||||
}
|
||||
// 加这一行是为了撑开整个表格
|
||||
res += "|------------|-------------------------------------------------------|-------| ----------------| ---------------|-------------|"
|
||||
return res
|
||||
}
|
||||
|
||||
// AvailableTable define
|
||||
func (mds Mdrows) AvailableTable() string {
|
||||
return mds.table()
|
||||
}
|
52
ctl/meta/Array
Normal file
52
ctl/meta/Array
Normal file
@ -0,0 +1,52 @@
|
||||
|1. Two Sum| [Go]({{< relref "/ChapterFour/0001.Two-Sum.md" >}})| Easy | O(n)| O(n)||
|
||||
|11. Container With Most Water| [Go]({{< relref "/ChapterFour/0011.Container-With-Most-Water.md" >}})| Medium | O(n)| O(1)||
|
||||
|15. 3Sum | [Go]({{< relref "/ChapterFour/0015.3Sum.md" >}})| Medium | O(n^2)| O(n)|❤️|
|
||||
|16. 3Sum Closest | [Go]({{< relref "/ChapterFour/0016.3Sum-Closest.md" >}})| Medium | O(n^2)| O(1)|❤️|
|
||||
|18. 4Sum | [Go]({{< relref "/ChapterFour/0018.4Sum.md" >}})| Medium | O(n^3)| O(n^2)|❤️|
|
||||
|26. Remove Duplicates from Sorted Array | [Go]({{< relref "/ChapterFour/0026.Remove-Duplicates-from-Sorted-Array.md" >}})| Easy | O(n)| O(1)||
|
||||
|27. Remove Element | [Go]({{< relref "/ChapterFour/0027.Remove-Element.md" >}})| Easy | O(n)| O(1)||
|
||||
|39. Combination Sum | [Go]({{< relref "/ChapterFour/0039.Combination-Sum.md" >}})| Medium | O(n log n)| O(n)||
|
||||
|40. Combination Sum II | [Go]({{< relref "/ChapterFour/0040.Combination-Sum-II.md" >}})| Medium | O(n log n)| O(n)||
|
||||
|41. First Missing Positive | [Go]({{< relref "/ChapterFour/0041.First-Missing-Positive.md" >}})| Hard | O(n)| O(n)||
|
||||
|42. Trapping Rain Water | [Go]({{< relref "/ChapterFour/0042.Trapping-Rain-Water.md" >}})| Hard | O(n)| O(1)|❤️|
|
||||
|48. Rotate Image | [Go]({{< relref "/ChapterFour/0048.Rotate-Image.md" >}})| Medium | O(n)| O(1)||
|
||||
|53. Maximum Subarray| [Go]({{< relref "/ChapterFour/0053.Maximum-Subarray.md" >}})| Easy | O(n)| O(n)||
|
||||
|54. Spiral Matrix| [Go]({{< relref "/ChapterFour/0054.Spiral-Matrix.md" >}})| Medium | O(n)| O(n^2)||
|
||||
|56. Merge Intervals | [Go]({{< relref "/ChapterFour/0056.Merge-Intervals.md" >}})| Medium | O(n log n)| O(1)||
|
||||
|57. Insert Interval | [Go]({{< relref "/ChapterFour/0057.Insert-Interval.md" >}})| Hard | O(n)| O(1)||
|
||||
|59. Spiral Matrix II | [Go]({{< relref "/ChapterFour/0059.Spiral-Matrix-II.md" >}})| Medium | O(n)| O(n^2)||
|
||||
|62. Unique Paths | [Go]({{< relref "/ChapterFour/0062.Unique-Paths.md" >}})| Medium | O(n^2)| O(n^2)||
|
||||
|63. Unique Paths II | [Go]({{< relref "/ChapterFour/0063.Unique-Paths-II.md" >}})| Medium | O(n^2)| O(n^2)||
|
||||
|64. Minimum Path Sum | [Go]({{< relref "/ChapterFour/0064.Minimum-Path-Sum.md" >}})| Medium | O(n^2)| O(n^2)||
|
||||
|75. Sort Colors | [Go]({{< relref "/ChapterFour/0075.Sort-Colors.md" >}})| Medium| O(n)| O(1)|❤️|
|
||||
|78. Subsets| [Go]({{< relref "/ChapterFour/0078.Subsets.md" >}})| Medium | O(n^2)| O(n)|❤️|
|
||||
|79. Word Search | [Go]({{< relref "/ChapterFour/0079.Word-Search.md" >}})| Medium | O(n^2)| O(n^2)|❤️|
|
||||
|80. Remove Duplicates from Sorted Array II| [Go]({{< relref "/ChapterFour/0080.Remove-Duplicates-from-Sorted-Array-II.md" >}})| Medium | O(n)| O(1||
|
||||
|84. Largest Rectangle in Histogram | [Go]({{< relref "/ChapterFour/0084.Largest-Rectangle-in-Histogram.md" >}})| Medium | O(n)| O(n)|❤️|
|
||||
|88. Merge Sorted Array | [Go]({{< relref "/ChapterFour/0088.Merge-Sorted-Array.md" >}})| Easy | O(n)| O(1)|❤️|
|
||||
|90. Subsets II | [Go]({{< relref "/ChapterFour/0090.Subsets-II.md" >}})| Medium | O(n^2)| O(n)|❤️|
|
||||
|120. Triangle | [Go]({{< relref "/ChapterFour/0120.Triangle.md" >}})| Medium | O(n^2)| O(n)||
|
||||
|121. Best Time to Buy and Sell Stock | [Go]({{< relref "/ChapterFour/0121.Best-Time-to-Buy-and-Sell-Stock.md" >}})| Easy | O(n)| O(1)||
|
||||
|122. Best Time to Buy and Sell Stock II | [Go]({{< relref "/ChapterFour/0122.Best-Time-to-Buy-and-Sell-Stock-II.md" >}})| Easy | O(n)| O(1)||
|
||||
|126. Word Ladder II | [Go]({{< relref "/ChapterFour/0126.Word-Ladder-II.md" >}})| Hard | O(n)| O(n^2)|❤️|
|
||||
|152. Maximum Product Subarray | [Go]({{< relref "/ChapterFour/0152.Maximum-Product-Subarray.md" >}})| Medium | O(n)| O(1)||
|
||||
|167. Two Sum II - Input array is sorted | [Go]({{< relref "/ChapterFour/0167.Two-Sum-II---Input-array-is-sorted.md" >}})| Easy | O(n)| O(1)||
|
||||
|209. Minimum Size Subarray Sum | [Go]({{< relref "/ChapterFour/0209.Minimum-Size-Subarray-Sum.md" >}})| Medium | O(n)| O(1)||
|
||||
|216. Combination Sum III | [Go]({{< relref "/ChapterFour/0216.Combination-Sum-III.md" >}})| Medium | O(n)| O(1)|❤️|
|
||||
|217. Contains Duplicate | [Go]({{< relref "/ChapterFour/0217.Contains-Duplicate.md" >}})| Easy | O(n)| O(n)||
|
||||
|219. Contains Duplicate II | [Go]({{< relref "/ChapterFour/0219.Contains-Duplicate-II.md" >}})| Easy | O(n)| O(n)||
|
||||
|283. Move Zeroes | [Go]({{< relref "/ChapterFour/0283.Move-Zeroes.md" >}})| Easy | O(n)| O(1)||
|
||||
|287. Find the Duplicate Number | [Go]({{< relref "/ChapterFour/0287.Find-the-Duplicate-Number.md" >}})| Easy | O(n)| O(1)|❤️|
|
||||
|532. K-diff Pairs in an Array | [Go]({{< relref "/ChapterFour/0532.K-diff-Pairs-in-an-Array.md" >}})| Easy | O(n)| O(n)||
|
||||
|566. Reshape the Matrix | [Go]({{< relref "/ChapterFour/0566.Reshape-the-Matrix.md" >}})| Easy | O(n^2)| O(n^2)||
|
||||
|628. Maximum Product of Three Numbers | [Go]({{< relref "/ChapterFour/0628.Maximum-Product-of-Three-Numbers.md" >}})| Easy | O(n)| O(1)||
|
||||
|713. Subarray Product Less Than K | [Go]({{< relref "/ChapterFour/0713.Subarray-Product-Less-Than-K.md" >}})| Medium | O(n)| O(1)||
|
||||
|714. Best Time to Buy and Sell Stock with Transaction Fee| [Go]({{< relref "/ChapterFour/0714.Best-Time-to-Buy-and-Sell-Stock-with-Transaction-Fee.md" >}})| Medium | O(n)| O(1)||
|
||||
|746. Min Cost Climbing Stairs | [Go]({{< relref "/ChapterFour/0746.Min-Cost-Climbing-Stairs.md" >}})| Easy | O(n)| O(1)||
|
||||
|766. Toeplitz Matrix | [Go]({{< relref "/ChapterFour/0766.Toeplitz-Matrix.md" >}})| Easy | O(n)| O(1)||
|
||||
|867. Transpose Matrix | [Go]({{< relref "/ChapterFour/0867.Transpose-Matrix.md" >}})| Easy | O(n)| O(1)||
|
||||
|891. Sum of Subsequence Widths | [Go]({{< relref "/ChapterFour/0891.Sum-of-Subsequence-Widths.md" >}})| Hard | O(n log n)| O(1)||
|
||||
|907. Sum of Subarray Minimums | [Go]({{< relref "/ChapterFour/0907.Sum-of-Subarray-Minimums.md" >}})| Medium | O(n)| O(n)|❤️|
|
||||
|922. Sort Array By Parity II | [Go]({{< relref "/ChapterFour/0922.Sort-Array-By-Parity-II.md" >}})| Medium | O(n)| O(1)||
|
||||
|969. Pancake Sorting | [Go]({{< relref "/ChapterFour/0969.Pancake-Sorting.md" >}})| Medium | O(n)| O(1)|❤️|
|
||||
|977. Squares of a Sorted Array | [Go]({{< relref "/ChapterFour/0977.Squares-of-a-Sorted-Array.md" >}})| Easy | O(n)| O(1)||
|
30
ctl/meta/Backtracking
Normal file
30
ctl/meta/Backtracking
Normal file
@ -0,0 +1,30 @@
|
||||
|17. Letter Combinations of a Phone Number | [Go]({{< relref "/ChapterFour/0017.Letter-Combinations-of-a-Phone-Number.md" >}})| Medium | O(log n)| O(1)||
|
||||
|22. Generate Parentheses| [Go]({{< relref "/ChapterFour/0022.Generate-Parentheses.md" >}})| Medium | O(log n)| O(1)||
|
||||
|37. Sudoku Solver | [Go]({{< relref "/ChapterFour/0037.Sudoku-Solver.md" >}})| Hard | O(n^2)| O(n^2)|❤️|
|
||||
|39. Combination Sum | [Go]({{< relref "/ChapterFour/0039.Combination-Sum.md" >}})| Medium | O(n log n)| O(n)||
|
||||
|40. Combination Sum II | [Go]({{< relref "/ChapterFour/0040.Combination-Sum-II.md" >}})| Medium | O(n log n)| O(n)||
|
||||
|46. Permutations | [Go]({{< relref "/ChapterFour/0046.Permutations.md" >}})| Medium | O(n)| O(n)|❤️|
|
||||
|47. Permutations II | [Go]({{< relref "/ChapterFour/0047.Permutations-II.md" >}})| Medium | O(n^2)| O(n)|❤️|
|
||||
|51. N-Queens | [Go]({{< relref "/ChapterFour/0051.N-Queens.md" >}})| Hard | O(n!)| O(n)|❤️|
|
||||
|52. N-Queens II | [Go]({{< relref "/ChapterFour/0052.N-Queens-II.md" >}})| Hard | O(n!)| O(n)|❤️|
|
||||
|60. Permutation Sequence | [Go]({{< relref "/ChapterFour/0060.Permutation-Sequence.md" >}})| Medium | O(n log n)| O(1)||
|
||||
|77. Combinations | [Go]({{< relref "/ChapterFour/0077.Combinations.md" >}})| Medium | O(n)| O(n)|❤️|
|
||||
|78. Subsets | [Go]({{< relref "/ChapterFour/0078.Subsets.md" >}})| Medium | O(n^2)| O(n)|❤️|
|
||||
|79. Word Search | [Go]({{< relref "/ChapterFour/0079.Word-Search.md" >}})| Medium | O(n^2)| O(n^2)|❤️|
|
||||
|89. Gray Codes | [Go]({{< relref "/ChapterFour/0089.Gray-Code.md" >}})| Medium | O(n)| O(1)||
|
||||
|90. Subsets II | [Go]({{< relref "/ChapterFour/0090.Subsets-II.md" >}})| Medium | O(n^2)| O(n)|❤️|
|
||||
|93. Restore IP Addresses | [Go]({{< relref "/ChapterFour/0093.Restore-IP-Addresses.md" >}})| Medium | O(n)| O(n)|❤️|
|
||||
|126. Word Ladder II | [Go]({{< relref "/ChapterFour/0126.Word-Ladder-II.md" >}})| Hard | O(n)| O(n^2)|❤️|
|
||||
|131. Palindrome Partitioning | [Go]({{< relref "/ChapterFour/0131.Palindrome-Partitioning.md" >}})| Medium | O(n)| O(n^2)|❤️|
|
||||
|211. Add and Search Word - Data structure design | [Go]({{< relref "/ChapterFour/0211.Add-and-Search-Word---Data-structure-design.md" >}})| Medium | O(n)| O(n)|❤️|
|
||||
|212. Word Search II | [Go]({{< relref "/ChapterFour/0212.Word-Search-II.md" >}})| Hard | O(n^2)| O(n^2)|❤️|
|
||||
|216. Combination Sum III | [Go]({{< relref "/ChapterFour/0216.Combination-Sum-III.md" >}})| Medium | O(n)| O(1)|❤️|
|
||||
|306. Additive Number | [Go]({{< relref "/ChapterFour/0306.Additive-Number.md" >}})| Medium | O(n^2)| O(1)|❤️|
|
||||
|357. Count Numbers with Unique Digits | [Go]({{< relref "/ChapterFour/0357.Count-Numbers-with-Unique-Digits.md" >}})| Medium | O(1)| O(1)||
|
||||
|401. Binary Watch | [Go]({{< relref "/ChapterFour/0401.Binary-Watch.md" >}})| Easy | O(1)| O(1)||
|
||||
|526. Beautiful Arrangement | [Go]({{< relref "/ChapterFour/0526.Beautiful-Arrangement.md" >}})| Medium | O(n^2)| O(1)|❤️|
|
||||
|784. Letter Case Permutation | [Go]({{< relref "/ChapterFour/0784.Letter-Case-Permutation.md" >}})| Easy | O(n)| O(n)||
|
||||
|842. Split Array into Fibonacci Sequence | [Go]({{< relref "/ChapterFour/0842.Split-Array-into-Fibonacci-Sequence.md" >}})| Medium | O(n^2)| O(1)|❤️|
|
||||
|980. Unique Paths III | [Go]({{< relref "/ChapterFour/0980.Unique-Paths-III.md" >}})| Hard | O(n log n)| O(n)||
|
||||
|996. Number of Squareful Arrays | [Go]({{< relref "/ChapterFour/0996.Number-of-Squareful-Arrays.md" >}})| Hard | O(n log n)| O(n) ||
|
||||
|1079. Letter Tile Possibilities | [Go]({{< relref "/ChapterFour/1079.Letter-Tile-Possibilities.md" >}})| Medium | O(n^2)| O(1)|❤️|
|
0
ctl/meta/Binary_Indexed_Tree
Normal file
0
ctl/meta/Binary_Indexed_Tree
Normal file
13
ctl/meta/Binary_Search
Normal file
13
ctl/meta/Binary_Search
Normal file
@ -0,0 +1,13 @@
|
||||
|50. Pow(x, n) | [Go]({{< relref "/ChapterFour/0050.Powx-n.md" >}})| Medium | O(log n)| O(1)||
|
||||
|69. Sqrt(x) | [Go]({{< relref "/ChapterFour/0069.Sqrtx.md" >}})| Easy | O(log n)| O(1)||
|
||||
|167. Two Sum II - Input array is sorted | [Go]({{< relref "/ChapterFour/0167.Two-Sum-II---Input-array-is-sorted.md" >}})| Easy | O(n)| O(1)||
|
||||
|209. Minimum Size Subarray Sum | [Go]({{< relref "/ChapterFour/0209.Minimum-Size-Subarray-Sum.md" >}})| Medium | O(n)| O(1)||
|
||||
|222. Count Complete Tree Nodes | [Go]({{< relref "/ChapterFour/0222.Count-Complete-Tree-Nodes.md" >}})| Medium | O(n)| O(1)||
|
||||
|230. Kth Smallest Element in a BST | [Go]({{< relref "/ChapterFour/0230.Kth-Smallest-Element-in-a-BST.md" >}})| Medium | O(n)| O(1)||
|
||||
|287. Find the Duplicate Number | [Go]({{< relref "/ChapterFour/0287.Find-the-Duplicate-Number.md" >}})| Easy | O(n)| O(1)|❤️|
|
||||
|300. Longest Increasing Subsequence | [Go]({{< relref "/ChapterFour/0300.Longest-Increasing-Subsequence.md" >}})| Medium | O(n log n)| O(n)||
|
||||
|349. Intersection of Two Arrays | [Go]({{< relref "/ChapterFour/0349.Intersection-of-Two-Arrays.md" >}})| Easy | O(n)| O(n) ||
|
||||
|350. Intersection of Two Arrays II | [Go]({{< relref "/ChapterFour/0350.Intersection-of-Two-Arrays-II.md" >}})| Easy | O(n)| O(n) ||
|
||||
|392. Is Subsequence | [Go]({{< relref "/ChapterFour/0392.Is-Subsequence.md" >}})| Medium | O(n)| O(1)||
|
||||
|454. 4Sum II | [Go]({{< relref "/ChapterFour/0454.4Sum-II.md" >}})| Medium | O(n^2)| O(n) ||
|
||||
|710. Random Pick with Blacklist | [Go]({{< relref "/ChapterFour/0710.Random-Pick-with-Blacklist.md" >}})| Hard | O(n)| O(n) ||
|
29
ctl/meta/Bit_Manipulation
Normal file
29
ctl/meta/Bit_Manipulation
Normal file
@ -0,0 +1,29 @@
|
||||
|78. Subsets | [Go]({{< relref "/ChapterFour/0078.Subsets.md" >}})| Medium | O(n^2)| O(n)|❤️|
|
||||
|136. Single Number | [Go]({{< relref "/ChapterFour/0136.Single-Number.md" >}})| Easy | O(n)| O(1)||
|
||||
|137. Single Number II | [Go]({{< relref "/ChapterFour/0137.Single-Number-II.md" >}})| Medium | O(n)| O(1)|❤️|
|
||||
|169. Majority Element | [Go]({{< relref "/ChapterFour/0169.Majority-Element.md" >}})| Easy | O(n)| O(1)|❤️|
|
||||
|187. Repeated DNA Sequences | [Go]({{< relref "/ChapterFour/0187.Repeated-DNA-Sequences.md" >}})| Medium | O(n)| O(1)||
|
||||
|190. Reverse Bits | [Go]({{< relref "/ChapterFour/0190.Reverse-Bits.md" >}})| Easy | O(n)| O(1)|❤️|
|
||||
|191. Number of 1 Bits | [Go]({{< relref "/ChapterFour/0191.Number-of-1-Bits.md" >}})| Easy | O(n)| O(1)||
|
||||
|201. Bitwise AND of Numbers Range | [Go]({{< relref "/ChapterFour/0201.Bitwise-AND-of-Numbers-Range.md" >}})| Medium | O(n)| O(1)|❤️|
|
||||
|231. Power of Two | [Go]({{< relref "/ChapterFour/0231.Power-of-Two.md" >}})| Easy | O(1)| O(1)||
|
||||
|260. Single Number III | [Go]({{< relref "/ChapterFour/0260.Single-Number-III.md" >}})| Medium | O(n)| O(1)|❤️|
|
||||
|268. Missing Number | [Go]({{< relref "/ChapterFour/0268.Missing-Number.md" >}})| Easy | O(n)| O(1)||
|
||||
|318. Maximum Product of Word Lengths | [Go]({{< relref "/ChapterFour/0318.Maximum-Product-of-Word-Lengths.md" >}})| Medium | O(n)| O(1)||
|
||||
|338. Counting Bits | [Go]({{< relref "/ChapterFour/0338.Counting-Bits.md" >}})| Medium | O(n)| O(n)||
|
||||
|342. Power of Four | [Go]({{< relref "/ChapterFour/0342.Power-of-Four.md" >}})| Easy | O(n)| O(1)||
|
||||
|371. Sum of Two Integers | [Go]({{< relref "/ChapterFour/0371.Sum-of-Two-Integers.md" >}})| Easy | O(n)| O(1)||
|
||||
|389. Find the Difference | [Go]({{< relref "/ChapterFour/0389.Find-the-Difference.md" >}})| Easy | O(n)| O(1)||
|
||||
|393. UTF-8 Validation | [Go]({{< relref "/ChapterFour/0393.UTF-8-Validation.md" >}})| Medium | O(n)| O(1)||
|
||||
|397. Integer Replacement | [Go]({{< relref "/ChapterFour/0397.Integer-Replacement.md" >}})| Medium | O(n)| O(1)||
|
||||
|401. Binary Watch | [Go]({{< relref "/ChapterFour/0401.Binary-Watch.md" >}})| Easy | O(1)| O(1)||
|
||||
|405. Convert a Number to Hexadecimal | [Go]({{< relref "/ChapterFour/0405.Convert-a-Number-to-Hexadecimal.md" >}})| Easy | O(n)| O(1)||
|
||||
|421. Maximum XOR of Two Numbers in an Array | [Go]({{< relref "/ChapterFour/0421.Maximum-XOR-of-Two-Numbers-in-an-Array.md" >}})| Medium | O(n)| O(1)|❤️|
|
||||
|461. Hamming Distance | [Go]({{< relref "/ChapterFour/0461.Hamming-Distance.md" >}})| Easy | O(n)| O(1)||
|
||||
|476. Number Complement | [Go]({{< relref "/ChapterFour/0476.Number-Complement.md" >}})| Easy | O(n)| O(1)||
|
||||
|477. Total Hamming Distance | [Go]({{< relref "/ChapterFour/0477.Total-Hamming-Distance.md" >}})| Medium | O(n)| O(1)||
|
||||
|693. Binary Number with Alternating Bits | [Go]({{< relref "/ChapterFour/0693.Binary-Number-with-Alternating-Bits.md" >}})| Easy | O(n)| O(1)|❤️|
|
||||
|756. Pyramid Transition Matrix | [Go]({{< relref "/ChapterFour/0756.Pyramid-Transition-Matrix.md" >}})| Medium | O(n log n)| O(n)||
|
||||
|762. Prime Number of Set Bits in Binary Representation | [Go]({{< relref "/ChapterFour/0762.Prime-Number-of-Set-Bits-in-Binary-Representation.md" >}})| Easy | O(n)| O(1)||
|
||||
|784. Letter Case Permutation | [Go]({{< relref "/ChapterFour/0784.Letter-Case-Permutation.md" >}})| Easy | O(n)| O(1)||
|
||||
|898. Bitwise ORs of Subarrays | [Go]({{< relref "/ChapterFour/0898.Bitwise-ORs-of-Subarrays.md" >}})| Medium | O(n)| O(1)||
|
14
ctl/meta/Breadth_First_Search
Normal file
14
ctl/meta/Breadth_First_Search
Normal file
@ -0,0 +1,14 @@
|
||||
|101. Symmetric Tree | [Go]({{< relref "/ChapterFour/0101.Symmetric-Tree.md" >}})| Easy | O(n)| O(1)||
|
||||
|102. Binary Tree Level Order Traversal | [Go]({{< relref "/ChapterFour/0102.Binary-Tree-Level-Order-Traversal.md" >}})| Medium | O(n)| O(1)||
|
||||
|103. Binary Tree Zigzag Level Order Traversal | [Go]({{< relref "/ChapterFour/0103.Binary-Tree-Zigzag-Level-Order-Traversal.md" >}})| Medium | O(n)| O(n)||
|
||||
|107. Binary Tree Level Order Traversal II | [Go]({{< relref "/ChapterFour/0107.Binary-Tree-Level-Order-Traversal-II.md" >}})| Easy | O(n)| O(1)||
|
||||
|111. Minimum Depth of Binary Tree | [Go]({{< relref "/ChapterFour/0111.Minimum-Depth-of-Binary-Tree.md" >}})| Easy | O(n)| O(1)||
|
||||
|126. Word Ladder II | [Go]({{< relref "/ChapterFour/0126.Word-Ladder-II.md" >}})| Hard | O(n)| O(n^2)|❤️|
|
||||
|127. Word Ladder | [Go]({{< relref "/ChapterFour/0127.Word-Ladder.md" >}})| Medium | O(n)| O(n)||
|
||||
|199. Binary Tree Right Side View | [Go]({{< relref "/ChapterFour/0199.Binary-Tree-Right-Side-View.md" >}})| Medium | O(n)| O(1)||
|
||||
|200. Number of Islands | [Go]({{< relref "/ChapterFour/0200.Number-of-Islands.md" >}})| Medium | O(n^2)| O(n^2)||
|
||||
|207. Course Schedule | [Go]({{< relref "/ChapterFour/0207.Course-Schedule.md" >}})| Medium | O(n^2)| O(n^2)||
|
||||
|210. Course Schedule II | [Go]({{< relref "/ChapterFour/0210.Course-Schedule-II.md" >}})| Medium | O(n^2)| O(n^2)||
|
||||
|515. Find Largest Value in Each Tree Row | [Go]({{< relref "/ChapterFour/0515.Find-Largest-Value-in-Each-Tree-Row.md" >}})| Medium | O(n)| O(n)||
|
||||
|542. 01 Matrix | [Go]({{< relref "/ChapterFour/0542.01-Matrix.md" >}})| Medium | O(n)| O(1)||
|
||||
|993. Cousins in Binary Tree | [Go]({{< relref "/ChapterFour/0993.Cousins-in-Binary-Tree.md" >}})| Easy | O(n)| O(1)||
|
23
ctl/meta/Depth_First_Search
Normal file
23
ctl/meta/Depth_First_Search
Normal file
@ -0,0 +1,23 @@
|
||||
|98. Validate Binary Search Tree | [Go]({{< relref "/ChapterFour/0098.Validate-Binary-Search-Tree.md" >}})| Medium | O(n)| O(1)||
|
||||
|99. Recover Binary Search Tree | [Go]({{< relref "/ChapterFour/0099.Recover-Binary-Search-Tree.md" >}})| Hard | O(n)| O(1)||
|
||||
|100. Same Tree | [Go]({{< relref "/ChapterFour/0100.Same-Tree.md" >}})| Easy | O(n)| O(1)||
|
||||
|101. Symmetric Tree | [Go]({{< relref "/ChapterFour/0101.Symmetric-Tree.md" >}})| Easy | O(n)| O(1)||
|
||||
|104. Maximum Depth of Binary Tree | [Go]({{< relref "/ChapterFour/0104.Maximum-Depth-of-Binary-Tree.md" >}})| Easy | O(n)| O(1)||
|
||||
|108. Convert Sorted Array to Binary Search Tree | [Go]({{< relref "/ChapterFour/0108.Convert-Sorted-Array-to-Binary-Search-Tree.md" >}})| Easy | O(n)| O(1)||
|
||||
|109. Convert Sorted List to Binary Search Tree | [Go]({{< relref "/ChapterFour/0109.Convert-Sorted-List-to-Binary-Search-Tree.md" >}})| Medium | O(log n)| O(n)||
|
||||
|110. Balanced Binary Tree | [Go]({{< relref "/ChapterFour/0110.Balanced-Binary-Tree.md" >}})| Easy | O(n)| O(1)||
|
||||
|111. Minimum Depth of Binary Tree | [Go]({{< relref "/ChapterFour/0111.Minimum-Depth-of-Binary-Tree.md" >}})| Easy | O(n)| O(1)||
|
||||
|112. Path Sum | [Go]({{< relref "/ChapterFour/0112.Path-Sum.md" >}})| Easy | O(n)| O(1)||
|
||||
|113. Path Sum II | [Go]({{< relref "/ChapterFour/0113.Path-Sum-II.md" >}})| Medium | O(n)| O(1)||
|
||||
|114. Flatten Binary Tree to Linked List | [Go]({{< relref "/ChapterFour/0114.Flatten-Binary-Tree-to-Linked-List.md" >}})| Medium | O(n)| O(1)||
|
||||
|124. Binary Tree Maximum Path Sum | [Go]({{< relref "/ChapterFour/0124.Binary-Tree-Maximum-Path-Sum.md" >}})| Hard | O(n)| O(1)||
|
||||
|129. Sum Root to Leaf Numbers | [Go]({{< relref "/ChapterFour/0129.Sum-Root-to-Leaf-Numbers.md" >}})| Medium | O(n)| O(1)||
|
||||
|199. Binary Tree Right Side View | [Go]({{< relref "/ChapterFour/0199.Binary-Tree-Right-Side-View.md" >}})| Medium | O(n)| O(1)||
|
||||
|200. Number of Islands | [Go]({{< relref "/ChapterFour/0200.Number-of-Islands.md" >}})| Medium | O(n^2)| O(n^2)||
|
||||
|207. Course Schedule | [Go]({{< relref "/ChapterFour/0207.Course-Schedule.md" >}})| Medium | O(n^2)| O(n^2)||
|
||||
|210. Course Schedule II | [Go]({{< relref "/ChapterFour/0210.Course-Schedule-II.md" >}})| Medium | O(n^2)| O(n^2)||
|
||||
|257. Binary Tree Paths | [Go]({{< relref "/ChapterFour/0257.Binary-Tree-Paths.md" >}})| Easy | O(n)| O(1)||
|
||||
|394. Decode String | [Go]({{< relref "/ChapterFour/0394.Decode-String.md" >}})| Medium | O(n)| O(n)||
|
||||
|515. Find Largest Value in Each Tree Row | [Go]({{< relref "/ChapterFour/0515.Find-Largest-Value-in-Each-Tree-Row.md" >}})| Medium | O(n)| O(n)||
|
||||
|542. 01 Matrix | [Go]({{< relref "/ChapterFour/0542.01-Matrix.md" >}})| Medium | O(n)| O(1)||
|
||||
|980. Unique Paths III | [Go]({{< relref "/ChapterFour/0980.Unique-Paths-III.md" >}})| Hard | O(n log n)| O(n)||
|
26
ctl/meta/Dynamic_Programming
Normal file
26
ctl/meta/Dynamic_Programming
Normal file
@ -0,0 +1,26 @@
|
||||
|53. Maximum Subarray| [Go]({{< relref "/ChapterFour/0053.Maximum-Subarray.md" >}})| Easy | O(n)| O(n)||
|
||||
|62. Unique Paths | [Go]({{< relref "/ChapterFour/0062.Unique-Paths.md" >}})| Medium | O(n^2)| O(n^2)||
|
||||
|63. Unique Paths II | [Go]({{< relref "/ChapterFour/0063.Unique-Paths-II.md" >}})| Medium | O(n^2)| O(n^2)||
|
||||
|64. Minimum Path Sum | [Go]({{< relref "/ChapterFour/0064.Minimum-Path-Sum.md" >}})| Medium | O(n^2)| O(n^2)||
|
||||
|70. Climbing Stairs | [Go]({{< relref "/ChapterFour/0070.Climbing-Stairs.md" >}})| Easy | O(n)| O(n)||
|
||||
|91. Decode Ways | [Go]({{< relref "/ChapterFour/0091.Decode-Ways.md" >}})| Medium | O(n)| O(n)||
|
||||
|96. Unique Binary Search Trees | [Go]({{< relref "/ChapterFour/0096.Unique-Binary-Search-Trees.md" >}})| Medium | O(n)| O(n)||
|
||||
|120. Triangle | [Go]({{< relref "/ChapterFour/0120.Triangle.md" >}})| Medium | O(n^2)| O(n)||
|
||||
|121. Best Time to Buy and Sell Stock | [Go]({{< relref "/ChapterFour/0121.Best-Time-to-Buy-and-Sell-Stock.md" >}})| Easy | O(n)| O(1)||
|
||||
|152. Maximum Product Subarray | [Go]({{< relref "/ChapterFour/0152.Maximum-Product-Subarray.md" >}})| Medium | O(n)| O(1)||
|
||||
|198. House Robber | [Go]({{< relref "/ChapterFour/0198.House-Robber.md" >}})| Easy | O(n)| O(n)||
|
||||
|213. House Robber II | [Go]({{< relref "/ChapterFour/0213.House-Robber-II.md" >}})| Medium | O(n)| O(n)||
|
||||
|300. Longest Increasing Subsequence | [Go]({{< relref "/ChapterFour/0300.Longest-Increasing-Subsequence.md" >}})| Medium | O(n log n)| O(n)||
|
||||
|309. Best Time to Buy and Sell Stock with Cooldown | [Go]({{< relref "/ChapterFour/0309.Best-Time-to-Buy-and-Sell-Stock-with-Cooldown.md" >}})| Medium | O(n)| O(n)||
|
||||
|322. Coin Change | [Go]({{< relref "/ChapterFour/0322.Coin-Change.md" >}})| Medium | O(n)| O(n)||
|
||||
|338. Counting Bits | [Go]({{< relref "/ChapterFour/0338.Counting-Bits.md" >}})| Medium | O(n)| O(n)||
|
||||
|343. Integer Break | [Go]({{< relref "/ChapterFour/0343.Integer-Break.md" >}})| Medium | O(n^2)| O(n)||
|
||||
|357. Count Numbers with Unique Digits | [Go]({{< relref "/ChapterFour/0357.Count-Numbers-with-Unique-Digits.md" >}})| Medium | O(1)| O(1)||
|
||||
|392. Is Subsequence | [Go]({{< relref "/ChapterFour/0392.Is-Subsequence.md" >}})| Medium | O(n)| O(1)||
|
||||
|416. Partition Equal Subset Sum | [Go]({{< relref "/ChapterFour/0416.Partition-Equal-Subset-Sum.md" >}})| Medium | O(n^2)| O(n)||
|
||||
|714. Best Time to Buy and Sell Stock with Transaction Fee | [Go]({{< relref "/ChapterFour/0714.Best-Time-to-Buy-and-Sell-Stock-with-Transaction-Fee.md" >}})| Medium | O(n)| O(1)||
|
||||
|746. Min Cost Climbing Stairs | [Go]({{< relref "/ChapterFour/0746.Min-Cost-Climbing-Stairs.md" >}})| Easy | O(n)| O(1)||
|
||||
|838. Push Dominoes | [Go]({{< relref "/ChapterFour/0838.Push-Dominoes.md" >}})| Medium | O(n)| O(n)||
|
||||
|1025. Divisor Game | [Go]({{< relref "/ChapterFour/1025.Divisor-Game.md" >}})| Easy | O(1)| O(1)||
|
||||
|891. Sum of Subsequence Widths | [Go]({{< relref "/ChapterFour/0891.Sum-of-Subsequence-Widths.md" >}})| Hard | O(n log n)| O(1)||
|
||||
|942. DI String Match | [Go]({{< relref "/ChapterFour/0942.DI-String-Match.md" >}})| Easy | O(n)| O(1)||
|
33
ctl/meta/Hash_Table
Normal file
33
ctl/meta/Hash_Table
Normal file
@ -0,0 +1,33 @@
|
||||
|1. Two Sum | [Go]({{< relref "/ChapterFour/0001.Two-Sum.md" >}})| Easy | O(n)| O(n)||
|
||||
|3. Longest Substring Without Repeating Characters | [Go]({{< relref "/ChapterFour/0003.Longest-Substring-Without-Repeating-Characters.md" >}})| Medium | O(n)| O(1)|❤️|
|
||||
|18. 4Sum | [Go]({{< relref "/ChapterFour/0018.4Sum.md" >}})| Medium | O(n^3)| O(n^2)|❤️|
|
||||
|30. Substring with Concatenation of All Words | [Go]({{< relref "/ChapterFour/0030.Substring-with-Concatenation-of-All-Words.md" >}})| Hard | O(n)| O(n)|❤️|
|
||||
|36. Valid Sudoku | [Go]({{< relref "/ChapterFour/0036.Valid-Sudoku.md" >}})| Medium | O(n^2)| O(n^2)||
|
||||
|37. Sudoku Solver | [Go]({{< relref "/ChapterFour/0037.Sudoku-Solver.md" >}})| Hard | O(n^2)| O(n^2)|❤️|
|
||||
|49. Group Anagrams | [Go]({{< relref "/ChapterFour/0049.Group-Anagrams.md" >}})| Medium | O(n log n)| O(n)||
|
||||
|76. Minimum Window Substring | [Go]({{< relref "/ChapterFour/0076.Minimum-Window-Substring.md" >}})| Hard | O(n)| O(n)|❤️|
|
||||
|94. Binary Tree Inorder Traversal | [Go]({{< relref "/ChapterFour/0094.Binary-Tree-Inorder-Traversal.md" >}})| Medium | O(n)| O(1)||
|
||||
|138. Copy List with Random Pointer | [Go]()| Medium | O(n)| O(1)||
|
||||
|202. Happy Number | [Go]({{< relref "/ChapterFour/0202.Happy-Number.md" >}})| Easy | O(log n)| O(1)||
|
||||
|205. Isomorphic Strings | [Go]({{< relref "/ChapterFour/0205.Isomorphic-Strings.md" >}})| Easy | O(log n)| O(n)||
|
||||
|217. Contains Duplicate | [Go]({{< relref "/ChapterFour/0217.Contains-Duplicate.md" >}})| Easy | O(n)| O(n)||
|
||||
|219. Contains Duplicate II | [Go]({{< relref "/ChapterFour/0219.Contains-Duplicate-II.md" >}})| Easy | O(n)| O(n)||
|
||||
|242. Valid Anagram | [Go]({{< relref "/ChapterFour/0242.Valid-Anagram.md" >}})| Easy | O(n)| O(n) ||
|
||||
|274. H-Index | [Go]({{< relref "/ChapterFour/0274.H-Index.md" >}})| Medium | O(n)| O(n) ||
|
||||
|290. Word Pattern | [Go]({{< relref "/ChapterFour/0290.Word-Pattern.md" >}})| Easy | O(n)| O(n) ||
|
||||
|347. Top K Frequent Elements | [Go]({{< relref "/ChapterFour/0347.Top-K-Frequent-Elements.md" >}})| Medium | O(n)| O(n) ||
|
||||
|349. Intersection of Two Arrays | [Go]({{< relref "/ChapterFour/0349.Intersection-of-Two-Arrays.md" >}})| Easy | O(n)| O(n) ||
|
||||
|350. Intersection of Two Arrays II | [Go]({{< relref "/ChapterFour/0350.Intersection-of-Two-Arrays-II.md" >}})| Easy | O(n)| O(n) ||
|
||||
|438. Find All Anagrams in a String | [Go]({{< relref "/ChapterFour/0438.Find-All-Anagrams-in-a-String.md" >}})| Easy | O(n)| O(1) ||
|
||||
|447. Number of Boomerangs | [Go]({{< relref "/ChapterFour/0447.Number-of-Boomerangs.md" >}})| Easy | O(n)| O(1) ||
|
||||
|451. Sort Characters By Frequency | [Go]({{< relref "/ChapterFour/0451.Sort-Characters-By-Frequency.md" >}})| Medium | O(n log n)| O(1) ||
|
||||
|454. 4Sum II | [Go]({{< relref "/ChapterFour/0454.4Sum-II.md" >}})| Medium | O(n^2)| O(n) ||
|
||||
|648. Replace Words | [Go]({{< relref "/ChapterFour/0648.Replace-Words.md" >}})| Medium | O(n)| O(n) ||
|
||||
|676. Implement Magic Dictionary | [Go]({{< relref "/ChapterFour/0676.Implement-Magic-Dictionary.md" >}})| Medium | O(n)| O(n) ||
|
||||
|720. Longest Word in Dictionary | [Go]({{< relref "/ChapterFour/0720.Longest-Word-in-Dictionary.md" >}})| Easy | O(n)| O(n) ||
|
||||
|726. Number of Atoms | [Go]({{< relref "/ChapterFour/0726.Number-of-Atoms.md" >}})| Hard | O(n)| O(n) |❤️|
|
||||
|739. Daily Temperatures | [Go]({{< relref "/ChapterFour/0739.Daily-Temperatures.md" >}})| Medium | O(n)| O(n) ||
|
||||
|710. Random Pick with Blacklist | [Go]({{< relref "/ChapterFour/0710.Random-Pick-with-Blacklist.md" >}})| Hard | O(n)| O(n) ||
|
||||
|895. Maximum Frequency Stack | [Go]({{< relref "/ChapterFour/0895.Maximum-Frequency-Stack.md" >}})| Hard | O(n)| O(n) ||
|
||||
|930. Binary Subarrays With Sum | [Go]({{< relref "/ChapterFour/0930.Binary-Subarrays-With-Sum.md" >}})| Medium | O(n)| O(n) |❤️|
|
||||
|992. Subarrays with K Different Integers | [Go]({{< relref "/ChapterFour/0992.Subarrays-with-K-Different-Integers.md" >}})| Hard | O(n)| O(n) |❤️|
|
29
ctl/meta/Linked_List
Normal file
29
ctl/meta/Linked_List
Normal file
@ -0,0 +1,29 @@
|
||||
|2. Add Two Numbers | [Go]({{< relref "/ChapterFour/0002.Add-Two-Numbers.md" >}})| Medium | O(n)| O(1)||
|
||||
|19. Remove Nth Node From End of List | [Go]({{< relref "/ChapterFour/0019.Remove-Nth-Node-From-End-of-List.md" >}})| Medium | O(n)| O(1)||
|
||||
|21. Merge Two Sorted Lists | [Go]({{< relref "/ChapterFour/0021.Merge-Two-Sorted-Lists.md" >}})| Easy | O(log n)| O(1)||
|
||||
|23. Merge k Sorted Lists| [Go]({{< relref "/ChapterFour/0023.Merge-k-Sorted-Lists.md" >}})| Hard | O(log n)| O(1)|❤️|
|
||||
|24. Swap Nodes in Pairs | [Go]({{< relref "/ChapterFour/0024.Swap-Nodes-in-Pairs.md" >}})| Medium | O(n)| O(1)||
|
||||
|25. Reverse Nodes in k-Group | [Go]({{< relref "/ChapterFour/0025.Reverse-Nodes-in-k-Group.md" >}})| Hard | O(log n)| O(1)|❤️|
|
||||
|61. Rotate List | [Go]({{< relref "/ChapterFour/0061.Rotate-List.md" >}})| Medium | O(n)| O(1)||
|
||||
|82. Remove Duplicates from Sorted List II | [Go]({{< relref "/ChapterFour/0082.Remove-Duplicates-from-Sorted-List-II.md" >}})| Medium | O(n)| O(1)||
|
||||
|83. Remove Duplicates from Sorted List | [Go]({{< relref "/ChapterFour/0083.Remove-Duplicates-from-Sorted-List.md" >}})| Easy | O(n)| O(1)||
|
||||
|86. Partition List | [Go]({{< relref "/ChapterFour/0086.Partition-List.md" >}})| Medium | O(n)| O(1)|❤️|
|
||||
|92. Reverse Linked List II | [Go]({{< relref "/ChapterFour/0092.Reverse-Linked-List-II.md" >}})| Medium | O(n)| O(1)|❤️|
|
||||
|109. Convert Sorted List to Binary Search Tree | [Go]({{< relref "/ChapterFour/0109.Convert-Sorted-List-to-Binary-Search-Tree.md" >}})| Medium | O(log n)| O(n)||
|
||||
|141. Linked List Cycle | [Go]({{< relref "/ChapterFour/0141.Linked-List-Cycle.md" >}})| Easy | O(n)| O(1)|❤️|
|
||||
|142. Linked List Cycle II | [Go]({{< relref "/ChapterFour/0142.Linked-List-Cycle-II.md" >}})| Medium | O(n)| O(1)|❤️|
|
||||
|143. Reorder List | [Go]({{< relref "/ChapterFour/0143.Reorder-List.md" >}})| Medium | O(n)| O(1)|❤️|
|
||||
|147. Insertion Sort List | [Go]({{< relref "/ChapterFour/0147.Insertion-Sort-List.md" >}})| Medium | O(n)| O(1)|❤️|
|
||||
|148. Sort List | [Go]({{< relref "/ChapterFour/0148.Sort-List.md" >}})| Medium | O(n log n)| O(n)|❤️|
|
||||
|160. Intersection of Two Linked Lists | [Go]({{< relref "/ChapterFour/0160.Intersection-of-Two-Linked-Lists.md" >}})| Easy | O(n)| O(1)|❤️|
|
||||
|203. Remove Linked List Elements | [Go]({{< relref "/ChapterFour/0203.Remove-Linked-List-Elements.md" >}})| Easy | O(n)| O(1)||
|
||||
|206. Reverse Linked List | [Go]({{< relref "/ChapterFour/0206.Reverse-Linked-List.md" >}})| Easy | O(n)| O(1)||
|
||||
|234. Palindrome Linked List | [Go]({{< relref "/ChapterFour/0234.Palindrome-Linked-List.md" >}})| Easy | O(n)| O(1)||
|
||||
|237. Delete Node in a Linked List | [Go]({{< relref "/ChapterFour/0237.Delete-Node-in-a-Linked-List.md" >}})| Easy | O(n)| O(1)||
|
||||
|328. Odd Even Linked List | [Go]({{< relref "/ChapterFour/0328.Odd-Even-Linked-List.md" >}})| Medium | O(n)| O(1)||
|
||||
|445. Add Two Numbers II | [Go]({{< relref "/ChapterFour/0445.Add-Two-Numbers-II.md" >}})| Medium | O(n)| O(n)||
|
||||
|725. Split Linked List in Parts | [Go]({{< relref "/ChapterFour/0725.Split-Linked-List-in-Parts.md" >}})| Medium | O(n)| O(1)||
|
||||
|817. Linked List Components | [Go]({{< relref "/ChapterFour/0817.Linked-List-Components.md" >}})| Medium | O(n)| O(1)||
|
||||
|707. Design Linked List | [Go]({{< relref "/ChapterFour/0707.Design-Linked-List.md" >}})| Easy | O(n)| O(1)||
|
||||
|876. Middle of the Linked List | [Go]({{< relref "/ChapterFour/0876.Middle-of-the-Linked-List.md" >}})| Easy | O(n)| O(1)|❤️|
|
||||
|1019. Next Greater Node In Linked List | [Go]({{< relref "/ChapterFour/1019.Next-Greater-Node-In-Linked-List.md" >}})| Medium | O(n)| O(1)||
|
18
ctl/meta/Math
Normal file
18
ctl/meta/Math
Normal file
@ -0,0 +1,18 @@
|
||||
|2. Add Two Numbers | [Go]({{< relref "/ChapterFour/0002.Add-Two-Numbers.md" >}})| Medium | O(n)| O(1)||
|
||||
|50. Pow(x, n) | [Go]({{< relref "/ChapterFour/0050.Powx-n.md" >}})| Medium | O(log n)| O(1)||
|
||||
|60. Permutation Sequence | [Go]({{< relref "/ChapterFour/0060.Permutation-Sequence.md" >}})| Medium | O(n log n)| O(1)||
|
||||
|69. Sqrt(x) | [Go]({{< relref "/ChapterFour/0069.Sqrtx.md" >}})| Easy | O(log n)| O(1)||
|
||||
|202. Happy Number | [Go]({{< relref "/ChapterFour/0202.Happy-Number.md" >}})| Easy | O(log n)| O(1)||
|
||||
|224. Basic Calculator | [Go]({{< relref "/ChapterFour/0224.Basic-Calculator.md" >}})| Hard | O(n)| O(n)||
|
||||
|231. Power of Two | [Go]({{< relref "/ChapterFour/0231.Power-of-Two.md" >}})| Easy | O(1)| O(1)||
|
||||
|263. Ugly Number | [Go]({{< relref "/ChapterFour/0263.Ugly-Number.md" >}})| Easy | O(log n)| O(1)||
|
||||
|326. Power of Three | [Go]({{< relref "/ChapterFour/0326.Power-of-Three.md" >}})| Easy | O(1)| O(1)||
|
||||
|343. Integer Break | [Go]({{< relref "/ChapterFour/0343.Integer-Break.md" >}})| Medium | O(n^2)| O(n)||
|
||||
|357. Count Numbers with Unique Digits | [Go]({{< relref "/ChapterFour/0357.Count-Numbers-with-Unique-Digits.md" >}})| Medium | O(1)| O(1)||
|
||||
|628. Maximum Product of Three Numbers | [Go]({{< relref "/ChapterFour/0628.Maximum-Product-of-Three-Numbers.md" >}})| Easy | O(n)| O(1)||
|
||||
|885. Spiral Matrix III | [Go]({{< relref "/ChapterFour/0885.Spiral-Matrix-III.md" >}})| Medium | O(n^2)| O(1)||
|
||||
|891. Sum of Subsequence Widths | [Go]({{< relref "/ChapterFour/0891.Sum-of-Subsequence-Widths.md" >}})| Hard | O(n log n)| O(1)||
|
||||
|942. DI String Match | [Go]({{< relref "/ChapterFour/0942.DI-String-Match.md" >}})| Easy | O(n)| O(1)||
|
||||
|976. Largest Perimeter Triangle | [Go]({{< relref "/ChapterFour/0976.Largest-Perimeter-Triangle.md" >}})| Easy | O(n log n)| O(log n) ||
|
||||
|996. Number of Squareful Arrays | [Go]({{< relref "/ChapterFour/0996.Number-of-Squareful-Arrays.md" >}})| Hard | O(n log n)| O(n) ||
|
||||
|1025. Divisor Game | [Go]({{< relref "/ChapterFour/1025.Divisor-Game.md" >}})| Easy | O(1)| O(1)||
|
12
ctl/meta/PDFPreface
Normal file
12
ctl/meta/PDFPreface
Normal file
@ -0,0 +1,12 @@
|
||||
<img src="https://books.halfrost.com/leetcode/logo.png" alt="logo" heigth="1300px" align="center"/>
|
||||
|
||||
|
||||
# 说明
|
||||
|
||||
此版本是 https://books.halfrost.com/leetcode 网页的离线版,由于网页版实时会更新,所以此 PDF 版难免会有一些排版或者错别字。如果读者遇到了,可以到网页版相应页面,点击页面 edit 按钮,提交 pr 进行更改。此 PDF 版本号是 V1.5.20。PDF 永久更新地址是 https://github.com/halfrost/leetcode-go/releases/,以版本号区分不同版本。笔者还是强烈推荐看在线版,有任何错误都会立即更新。如果觉得此书对刷题有一点点帮助,可以给此书点一个 star,鼓励一下笔者早点更新更多题解。
|
||||
|
||||
> 版本号说明,V1.5.20,1 是大版本号,5 代表当前题解中有几百题,目前是 520 题,所以第二个版本号是 5,20 代表当前题解中有几十题,目前是 520 题,所以第三个版本号是 20 。
|
||||
|
||||
# 目录
|
||||
|
||||
[toc]
|
10
ctl/meta/Segment_Tree
Normal file
10
ctl/meta/Segment_Tree
Normal file
@ -0,0 +1,10 @@
|
||||
|218. The Skyline Problem | [Go]({{< relref "/ChapterFour/0218.The-Skyline-Problem.md" >}})| Hard | O(n log n)| O(n)|❤️|
|
||||
|307. Range Sum Query - Mutable | [Go]({{< relref "/ChapterFour/0307.Range-Sum-Query---Mutable.md" >}})| Hard | O(1)| O(n)||
|
||||
|315. Count of Smaller Numbers After Self | [Go]({{< relref "/ChapterFour/0315.Count-of-Smaller-Numbers-After-Self.md" >}})| Hard | O(n log n)| O(n)||
|
||||
|327. Count of Range Sum | [Go]({{< relref "/ChapterFour/0327.Count-of-Range-Sum.md" >}})| Hard | O(n log n)| O(n)|❤️|
|
||||
|493. Reverse Pairs | [Go]({{< relref "/ChapterFour/0493.Reverse-Pairs.md" >}})| Hard | O(n log n)| O(n)||
|
||||
|699. Falling Squares | [Go]({{< relref "/ChapterFour/0699.Falling-Squares.md" >}})| Hard | O(n log n)| O(n)|❤️|
|
||||
|715. Range Module | [Go]({{< relref "/ChapterFour/0715.Range-Module.md" >}})| Hard | O(log n)| O(n)|❤️|
|
||||
|732. My Calendar III | [Go]({{< relref "/ChapterFour/0732.My-Calendar-III.md" >}})| Hard | O(log n)| O(n)|❤️|
|
||||
|850. Rectangle Area II | [Go]({{< relref "/ChapterFour/0850.Rectangle-Area-II.md" >}})| Hard | O(n log n)| O(n)|❤️|
|
||||
|1157. Online Majority Element In Subarray | [Go]({{< relref "/ChapterFour/1157.Online-Majority-Element-In-Subarray.md" >}})| Hard | O(log n)| O(n)|❤️|
|
13
ctl/meta/Sliding_Window
Normal file
13
ctl/meta/Sliding_Window
Normal file
@ -0,0 +1,13 @@
|
||||
|3. Longest Substring Without Repeating Characters | [Go]({{< relref "/ChapterFour/0003.Longest-Substring-Without-Repeating-Characters.md" >}})| Medium | O(n)| O(1)|❤️|
|
||||
|76. Minimum Window Substring | [Go]({{< relref "/ChapterFour/0076.Minimum-Window-Substring.md" >}})| Hard | O(n)| O(n)|❤️|
|
||||
|239. Sliding Window Maximum | [Go]({{< relref "/ChapterFour/0239.Sliding-Window-Maximum.md" >}})| Hard | O(n * k)| O(n)|❤️|
|
||||
|424. Longest Repeating Character Replacement | [Go]({{< relref "/ChapterFour/0424.Longest-Repeating-Character-Replacement.md" >}})| Medium | O(n)| O(1) ||
|
||||
|480. Sliding Window Median | [Go]({{< relref "/ChapterFour/0480.Sliding-Window-Median.md" >}})| Hard | O(n * log k)| O(k)|❤️|
|
||||
|567. Permutation in String | [Go]({{< relref "/ChapterFour/0567.Permutation-in-String.md" >}})| Medium | O(n)| O(1)|❤️|
|
||||
|978. Longest Turbulent Subarray | [Go]({{< relref "/ChapterFour/0978.Longest-Turbulent-Subarray.md" >}})| Medium | O(n)| O(1)|❤️|
|
||||
|992. Subarrays with K Different Integers | [Go]({{< relref "/ChapterFour/0992.Subarrays-with-K-Different-Integers.md" >}})| Hard | O(n)| O(n)|❤️|
|
||||
|995. Minimum Number of K Consecutive Bit Flips | [Go]({{< relref "/ChapterFour/0995.Minimum-Number-of-K-Consecutive-Bit-Flips.md" >}})| Hard | O(n)| O(1)|❤️|
|
||||
|1004. Max Consecutive Ones III | [Go]({{< relref "/ChapterFour/1004.Max-Consecutive-Ones-III.md" >}})| Medium | O(n)| O(1) ||
|
||||
|1040. Moving Stones Until Consecutive II | [Go]({{< relref "/ChapterFour/1040.Moving-Stones-Until-Consecutive-II.md" >}})| Medium | O(n log n)| O(1) |❤️|
|
||||
|1052. Grumpy Bookstore Owner | [Go]({{< relref "/ChapterFour/1052.Grumpy-Bookstore-Owner.md" >}})| Medium | O(n log n)| O(1) ||
|
||||
|1074. Number of Submatrices That Sum to Target | [Go]({{< relref "/ChapterFour/1074.Number-of-Submatrices-That-Sum-to-Target.md" >}})| Hard | O(n^3)| O(n) |❤️|
|
@ -1,25 +1,7 @@
|
||||
---
|
||||
title: Sort
|
||||
type: docs
|
||||
---
|
||||
|
||||
# Sort
|
||||
|
||||

|
||||
|
||||
- 深刻的理解多路快排。第 75 题。
|
||||
- 链表的排序,插入排序(第 147 题)和归并排序(第 148 题)
|
||||
- 桶排序和基数排序。第 164 题。
|
||||
- "摆动排序"。第 324 题。
|
||||
- 两两不相邻的排序。第 767 题,第 1054 题。
|
||||
- "饼子排序"。第 969 题。
|
||||
|
||||
| Title | Solution | Difficulty | Time | Space | 收藏 |
|
||||
| ----- | :--------: | :----------: | :----: | :-----: |:-----: |
|
||||
|56. Merge Intervals | [Go]({{< relref "/ChapterFour/0056.Merge-Intervals.md" >}})| Medium | O(n log n)| O(log n)||
|
||||
|57. Insert Interval | [Go]({{< relref "/ChapterFour/0057.Insert-Interval.md" >}})| Hard | O(n)| O(1)||
|
||||
|75. Sort Colors | [Go]({{< relref "/ChapterFour/0075.Sort-Colors.md" >}})| Medium| O(n)| O(1)|❤️|
|
||||
|147. Insertion Sort List | [Go]({{< relref "/ChapterFour/0147.Insertion-Sort-List.md" >}})| Medium | O(n)| O(1) |❤️|
|
||||
|147. Insertion Sort List | [Go]({{< relref "/ChapterFour/0147.Insertion-Sort-List.md" >}})| Medium | O(n^2)| O(1) |❤️|
|
||||
|148. Sort List | [Go]({{< relref "/ChapterFour/0148.Sort-List.md" >}})| Medium |O(n log n)| O(log n)|❤️|
|
||||
|164. Maximum Gap | [Go]({{< relref "/ChapterFour/0164.Maximum-Gap.md" >}})| Hard | O(n log n)| O(log n) |❤️|
|
||||
|179. Largest Number | [Go]({{< relref "/ChapterFour/0179.Largest-Number.md" >}})| Medium | O(n log n)| O(log n) |❤️|
|
||||
@ -38,5 +20,4 @@ type: docs
|
||||
|973. K Closest Points to Origin | [Go]({{< relref "/ChapterFour/0973.K-Closest-Points-to-Origin.md" >}})| Medium | O(n log n)| O(log n) ||
|
||||
|976. Largest Perimeter Triangle | [Go]({{< relref "/ChapterFour/0976.Largest-Perimeter-Triangle.md" >}})| Easy | O(n log n)| O(log n) ||
|
||||
|1030. Matrix Cells in Distance Order | [Go]({{< relref "/ChapterFour/1030.Matrix-Cells-in-Distance-Order.md" >}})| Easy | O(n^2)| O(1) ||
|
||||
|1054. Distant Barcodes | [Go]({{< relref "/ChapterFour/1054.Distant-Barcodes.md" >}})| Medium | O(n log n)| O(log n) |❤️|
|
||||
|---------------------------------------|---------------------------------|--------------------------|-----------------------|-----------|--------|
|
||||
|1054. Distant Barcodes | [Go]({{< relref "/ChapterFour/1054.Distant-Barcodes.md" >}})| Medium | O(n log n)| O(log n) |❤️|
|
37
ctl/meta/Stack
Normal file
37
ctl/meta/Stack
Normal file
@ -0,0 +1,37 @@
|
||||
|20. Valid Parentheses | [Go]({{< relref "/ChapterFour/0020.Valid-Parentheses.md" >}})| Easy | O(log n)| O(1)||
|
||||
|42. Trapping Rain Water | [Go]({{< relref "/ChapterFour/0042.Trapping-Rain-Water.md" >}})| Hard | O(n)| O(1)|❤️|
|
||||
|71. Simplify Path | [Go]({{< relref "/ChapterFour/0071.Simplify-Path.md" >}})| Medium | O(n)| O(n)|❤️|
|
||||
|84. Largest Rectangle in Histogram | [Go]({{< relref "/ChapterFour/0084.Largest-Rectangle-in-Histogram.md" >}})| Medium | O(n)| O(n)|❤️|
|
||||
|94. Binary Tree Inorder Traversal | [Go]({{< relref "/ChapterFour/0094.Binary-Tree-Inorder-Traversal.md" >}})| Medium | O(n)| O(1)||
|
||||
|103. Binary Tree Zigzag Level Order Traversal | [Go]({{< relref "/ChapterFour/0103.Binary-Tree-Zigzag-Level-Order-Traversal.md" >}})| Medium | O(n)| O(n)||
|
||||
|144. Binary Tree Preorder Traversal | [Go]({{< relref "/ChapterFour/0144.Binary-Tree-Preorder-Traversal.md" >}})| Medium | O(n)| O(1)||
|
||||
|145. Binary Tree Postorder Traversal | [Go]({{< relref "/ChapterFour/0145.Binary-Tree-Postorder-Traversal.md" >}})| Hard | O(n)| O(1)||
|
||||
|150. Evaluate Reverse Polish Notation | [Go]({{< relref "/ChapterFour/0150.Evaluate-Reverse-Polish-Notation.md" >}})| Medium | O(n)| O(1)||
|
||||
|155. Min Stack | [Go]({{< relref "/ChapterFour/0155.Min-Stack.md" >}})| Easy | O(n)| O(n)||
|
||||
|173. Binary Search Tree Iterator | [Go]({{< relref "/ChapterFour/0173.Binary-Search-Tree-Iterator.md" >}})| Medium | O(n)| O(1)||
|
||||
|224. Basic Calculator | [Go]({{< relref "/ChapterFour/0224.Basic-Calculator.md" >}})| Hard | O(n)| O(n)||
|
||||
|225. Implement Stack using Queues | [Go]({{< relref "/ChapterFour/0225.Implement-Stack-using-Queues.md" >}})| Easy | O(n)| O(n)||
|
||||
|232. Implement Queue using Stacks | [Go]({{< relref "/ChapterFour/0232.Implement-Queue-using-Stacks.md" >}})| Easy | O(n)| O(n)||
|
||||
|331. Verify Preorder Serialization of a Binary Tree | [Go]({{< relref "/ChapterFour/0331.Verify-Preorder-Serialization-of-a-Binary-Tree.md" >}})| Medium | O(n)| O(1)||
|
||||
|394. Decode String | [Go]({{< relref "/ChapterFour/0394.Decode-String.md" >}})| Medium | O(n)| O(n)||
|
||||
|402. Remove K Digits | [Go]({{< relref "/ChapterFour/0402.Remove-K-Digits.md" >}})| Medium | O(n)| O(1)||
|
||||
|456. 132 Pattern | [Go]({{< relref "/ChapterFour/0456.132-Pattern.md" >}})| Medium | O(n)| O(n)||
|
||||
|496. Next Greater Element I | [Go]({{< relref "/ChapterFour/0496.Next-Greater-Element-I.md" >}})| Easy | O(n)| O(n)||
|
||||
|503. Next Greater Element II | [Go]({{< relref "/ChapterFour/0503.Next-Greater-Element-II.md" >}})| Medium | O(n)| O(n)||
|
||||
|636. Exclusive Time of Functions | [Go]({{< relref "/ChapterFour/0636.Exclusive-Time-of-Functions.md" >}})| Medium | O(n)| O(n)||
|
||||
|682. Baseball Game | [Go]({{< relref "/ChapterFour/0682.Baseball-Game.md" >}})| Easy | O(n)| O(n)||
|
||||
|726. Number of Atoms | [Go]({{< relref "/ChapterFour/0726.Number-of-Atoms.md" >}})| Hard | O(n)| O(n) |❤️|
|
||||
|735. Asteroid Collision | [Go]({{< relref "/ChapterFour/0735.Asteroid-Collision.md" >}})| Medium | O(n)| O(n) ||
|
||||
|739. Daily Temperatures | [Go]({{< relref "/ChapterFour/0739.Daily-Temperatures.md" >}})| Medium | O(n)| O(n) ||
|
||||
|844. Backspace String Compare | [Go]({{< relref "/ChapterFour/0844.Backspace-String-Compare.md" >}})| Easy | O(n)| O(n) ||
|
||||
|856. Score of Parentheses | [Go]({{< relref "/ChapterFour/0856.Score-of-Parentheses.md" >}})| Medium | O(n)| O(n)||
|
||||
|880. Decoded String at Index | [Go]({{< relref "/ChapterFour/0880.Decoded-String-at-Index.md" >}})| Medium | O(n)| O(n)||
|
||||
|895. Maximum Frequency Stack | [Go]({{< relref "/ChapterFour/0895.Maximum-Frequency-Stack.md" >}})| Hard | O(n)| O(n) ||
|
||||
|901. Online Stock Span | [Go]({{< relref "/ChapterFour/0901.Online-Stock-Span.md" >}})| Medium | O(n)| O(n) ||
|
||||
|907. Sum of Subarray Minimums | [Go]({{< relref "/ChapterFour/0907.Sum-of-Subarray-Minimums.md" >}})| Medium | O(n)| O(n)|❤️|
|
||||
|921. Minimum Add to Make Parentheses Valid | [Go]({{< relref "/ChapterFour/0921.Minimum-Add-to-Make-Parentheses-Valid.md" >}})| Medium | O(n)| O(n)||
|
||||
|946. Validate Stack Sequences | [Go]({{< relref "/ChapterFour/0946.Validate-Stack-Sequences.md" >}})| Medium | O(n)| O(n)||
|
||||
|1003. Check If Word Is Valid After Substitutions | [Go]({{< relref "/ChapterFour/1003.Check-If-Word-Is-Valid-After-Substitutions.md" >}})| Medium | O(n)| O(1)||
|
||||
|1019. Next Greater Node In Linked List | [Go]({{< relref "/ChapterFour/1019.Next-Greater-Node-In-Linked-List.md" >}})| Medium | O(n)| O(1)||
|
||||
|1021. Remove Outermost Parentheses | [Go]({{< relref "/ChapterFour/1021.Remove-Outermost-Parentheses.md" >}})| Medium | O(n)| O(1)||
|
||||
|1047. Remove All Adjacent Duplicates In String | [Go]({{< relref "/ChapterFour/1047.Remove-All-Adjacent-Duplicates-In-String.md" >}})| Medium | O(n)| O(1)||
|
20
ctl/meta/String
Normal file
20
ctl/meta/String
Normal file
@ -0,0 +1,20 @@
|
||||
|3. Longest Substring Without Repeating Characters | [Go]({{< relref "/ChapterFour/0003.Longest-Substring-Without-Repeating-Characters.md" >}})| Medium | O(n)| O(1)|❤️|
|
||||
|17. Letter Combinations of a Phone Number | [Go]({{< relref "/ChapterFour/0017.Letter-Combinations-of-a-Phone-Number.md" >}})| Medium | O(log n)| O(1)||
|
||||
|20. Valid Parentheses | [Go]({{< relref "/ChapterFour/0020.Valid-Parentheses.md" >}})| Easy | O(log n)| O(1)||
|
||||
|22. Generate Parentheses | [Go]({{< relref "/ChapterFour/0022.Generate-Parentheses.md" >}})| Medium | O(log n)| O(1)||
|
||||
|28. Implement strStr() | [Go]({{< relref "/ChapterFour/0028.Implement-strStr.md" >}})| Easy | O(n)| O(1)||
|
||||
|30. Substring with Concatenation of All Words | [Go]({{< relref "/ChapterFour/0030.Substring-with-Concatenation-of-All-Words.md" >}})| Hard | O(n)| O(n)|❤️|
|
||||
|49. Group Anagrams | [Go]({{< relref "/ChapterFour/0049.Group-Anagrams.md" >}})| Medium | O(n log n)| O(n)||
|
||||
|71. Simplify Path | [Go]({{< relref "/ChapterFour/0071.Simplify-Path.md" >}})| Medium | O(n)| O(n)||
|
||||
|76. Minimum Window Substring | [Go]({{< relref "/ChapterFour/0076.Minimum-Window-Substring.md" >}})| Hard | O(n)| O(n)|❤️|
|
||||
|91. Decode Ways | [Go]({{< relref "/ChapterFour/0091.Decode-Ways.md" >}})| Medium | O(n)| O(n)||
|
||||
|93. Restore IP Addresses | [Go]({{< relref "/ChapterFour/0093.Restore-IP-Addresses.md" >}})| Medium | O(n)| O(n)|❤️|
|
||||
|125. Valid Palindrome | [Go]({{< relref "/ChapterFour/0125.Valid-Palindrome.md" >}})| Easy | O(n)| O(1)||
|
||||
|126. Word Ladder II | [Go]({{< relref "/ChapterFour/0126.Word-Ladder-II.md" >}})| Hard | O(n)| O(n^2)|❤️|
|
||||
|344. Reverse String | [Go]({{< relref "/ChapterFour/0344.Reverse-String.md" >}})| Easy | O(n)| O(1)||
|
||||
|345. Reverse Vowels of a String | [Go]({{< relref "/ChapterFour/0345.Reverse-Vowels-of-a-String.md" >}})| Easy | O(n)| O(1)||
|
||||
|767. Reorganize String | [Go]({{< relref "/ChapterFour/0767.Reorganize-String.md" >}})| Medium | O(n log n)| O(log n) |❤️|
|
||||
|842. Split Array into Fibonacci Sequence | [Go]({{< relref "/ChapterFour/0842.Split-Array-into-Fibonacci-Sequence.md" >}})| Medium | O(n^2)| O(1)|❤️|
|
||||
|856. Score of Parentheses | [Go]({{< relref "/ChapterFour/0856.Score-of-Parentheses.md" >}})| Medium | O(n)| O(n)||
|
||||
|925. Long Pressed Name | [Go]({{< relref "/ChapterFour/0925.Long-Pressed-Name.md" >}})| Easy | O(n)| O(1)||
|
||||
|1003. Check If Word Is Valid After Substitutions | [Go]({{< relref "/ChapterFour/1003.Check-If-Word-Is-Valid-After-Substitutions.md" >}})| Medium | O(n)| O(1)||
|
33
ctl/meta/Tree
Normal file
33
ctl/meta/Tree
Normal file
@ -0,0 +1,33 @@
|
||||
|94. Binary Tree Inorder Traversal | [Go]({{< relref "/ChapterFour/0094.Binary-Tree-Inorder-Traversal.md" >}})| Medium | O(n)| O(1)||
|
||||
|96. Unique Binary Search Trees | [Go]({{< relref "/ChapterFour/0096.Unique-Binary-Search-Trees.md" >}})| Medium | O(n^2)| O(n)||
|
||||
|98. Validate Binary Search Tree | [Go]({{< relref "/ChapterFour/0098.Validate-Binary-Search-Tree.md" >}})| Medium | O(n)| O(1)||
|
||||
|99. Recover Binary Search Tree | [Go]({{< relref "/ChapterFour/0099.Recover-Binary-Search-Tree.md" >}})| Hard | O(n)| O(1)||
|
||||
|100. Same Tree | [Go]({{< relref "/ChapterFour/0100.Same-Tree.md" >}})| Easy | O(n)| O(1)||
|
||||
|101. Symmetric Tree | [Go]({{< relref "/ChapterFour/0101.Symmetric-Tree.md" >}})| Easy | O(n)| O(1)||
|
||||
|102. Binary Tree Level Order Traversal | [Go]({{< relref "/ChapterFour/0102.Binary-Tree-Level-Order-Traversal.md" >}})| Medium | O(n)| O(1)||
|
||||
|103. Binary Tree Zigzag Level Order Traversal | [Go]({{< relref "/ChapterFour/0103.Binary-Tree-Zigzag-Level-Order-Traversal.md" >}})| Medium | O(n)| O(n)||
|
||||
|104. Maximum Depth of Binary Tree | [Go]({{< relref "/ChapterFour/0104.Maximum-Depth-of-Binary-Tree.md" >}})| Easy | O(n)| O(1)||
|
||||
|107. Binary Tree Level Order Traversal II | [Go]({{< relref "/ChapterFour/0107.Binary-Tree-Level-Order-Traversal-II.md" >}})| Easy | O(n)| O(1)||
|
||||
|108. Convert Sorted Array to Binary Search Tree | [Go]({{< relref "/ChapterFour/0108.Convert-Sorted-Array-to-Binary-Search-Tree.md" >}})| Easy | O(n)| O(1)||
|
||||
|110. Balanced Binary Tree | [Go]({{< relref "/ChapterFour/0110.Balanced-Binary-Tree.md" >}})| Easy | O(n)| O(1)||
|
||||
|111. Minimum Depth of Binary Tree | [Go]({{< relref "/ChapterFour/0111.Minimum-Depth-of-Binary-Tree.md" >}})| Easy | O(n)| O(1)||
|
||||
|112. Path Sum | [Go]({{< relref "/ChapterFour/0112.Path-Sum.md" >}})| Easy | O(n)| O(1)||
|
||||
|113. Path Sum II | [Go]({{< relref "/ChapterFour/0113.Path-Sum-II.md" >}})| Medium | O(n)| O(1)||
|
||||
|114. Flatten Binary Tree to Linked List | [Go]({{< relref "/ChapterFour/0114.Flatten-Binary-Tree-to-Linked-List.md" >}})| Medium | O(n)| O(1)||
|
||||
|124. Binary Tree Maximum Path Sum | [Go]({{< relref "/ChapterFour/0124.Binary-Tree-Maximum-Path-Sum.md" >}})| Hard | O(n)| O(1)||
|
||||
|129. Sum Root to Leaf Numbers | [Go]({{< relref "/ChapterFour/0129.Sum-Root-to-Leaf-Numbers.md" >}})| Medium | O(n)| O(1)||
|
||||
|144. Binary Tree Preorder Traversal | [Go]({{< relref "/ChapterFour/0144.Binary-Tree-Preorder-Traversal.md" >}})| Medium | O(n)| O(1)||
|
||||
|145. Binary Tree Postorder Traversal | [Go]({{< relref "/ChapterFour/0145.Binary-Tree-Postorder-Traversal.md" >}})| Hard | O(n)| O(1)||
|
||||
|173. Binary Search Tree Iterator | [Go]({{< relref "/ChapterFour/0173.Binary-Search-Tree-Iterator.md" >}})| Medium | O(n)| O(1)||
|
||||
|199. Binary Tree Right Side View | [Go]({{< relref "/ChapterFour/0199.Binary-Tree-Right-Side-View.md" >}})| Medium | O(n)| O(1)||
|
||||
|222. Count Complete Tree Nodes | [Go]({{< relref "/ChapterFour/0222.Count-Complete-Tree-Nodes.md" >}})| Medium | O(n)| O(1)||
|
||||
|226. Invert Binary Tree | [Go]({{< relref "/ChapterFour/0226.Invert-Binary-Tree.md" >}})| Easy | O(n)| O(1)||
|
||||
|230. Kth Smallest Element in a BST | [Go]({{< relref "/ChapterFour/0230.Kth-Smallest-Element-in-a-BST.md" >}})| Medium | O(n)| O(1)||
|
||||
|235. Lowest Common Ancestor of a Binary Search Tree | [Go]({{< relref "/ChapterFour/0235.Lowest-Common-Ancestor-of-a-Binary-Search-Tree.md" >}})| Easy | O(n)| O(1)||
|
||||
|236. Lowest Common Ancestor of a Binary Tree | [Go]({{< relref "/ChapterFour/0236.Lowest-Common-Ancestor-of-a-Binary-Tree.md" >}})| Medium | O(n)| O(1)||
|
||||
|257. Binary Tree Paths | [Go]({{< relref "/ChapterFour/0257.Binary-Tree-Paths.md" >}})| Easy | O(n)| O(1)||
|
||||
|404. Sum of Left Leaves | [Go]({{< relref "/ChapterFour/0404.Sum-of-Left-Leaves.md" >}})| Easy | O(n)| O(1)||
|
||||
|437. Path Sum III | [Go]({{< relref "/ChapterFour/0437.Path-Sum-III.md" >}})| Easy | O(n)| O(1)||
|
||||
|515. Find Largest Value in Each Tree Row | [Go]({{< relref "/ChapterFour/0515.Find-Largest-Value-in-Each-Tree-Row.md" >}})| Medium | O(n)| O(n)||
|
||||
|637. Average of Levels in Binary Tree | [Go]({{< relref "/ChapterFour/0637.Average-of-Levels-in-Binary-Tree.md" >}})| Easy | O(n)| O(n)||
|
||||
|993. Cousins in Binary Tree | [Go]({{< relref "/ChapterFour/0993.Cousins-in-Binary-Tree.md" >}})| Easy | O(n)| O(1)||
|
50
ctl/meta/Two_Pointers
Normal file
50
ctl/meta/Two_Pointers
Normal file
@ -0,0 +1,50 @@
|
||||
|3. Longest Substring Without Repeating Characters | [Go]({{< relref "/ChapterFour/0003.Longest-Substring-Without-Repeating-Characters.md" >}})| Medium | O(n)| O(1)|❤️|
|
||||
|11. Container With Most Water | [Go]({{< relref "/ChapterFour/0011.Container-With-Most-Water.md" >}})| Medium | O(n)| O(1)||
|
||||
|15. 3Sum | [Go]({{< relref "/ChapterFour/0015.3Sum.md" >}})| Medium | O(n^2)| O(n)|❤️|
|
||||
|16. 3Sum Closest | [Go]({{< relref "/ChapterFour/0016.3Sum-Closest.md" >}})| Medium | O(n^2)| O(1)|❤️|
|
||||
|18. 4Sum | [Go]({{< relref "/ChapterFour/0018.4Sum.md" >}})| Medium | O(n^3)| O(n^2)|❤️|
|
||||
|19. Remove Nth Node From End of List | [Go]({{< relref "/ChapterFour/0019.Remove-Nth-Node-From-End-of-List.md" >}})| Medium | O(n)| O(1)||
|
||||
|26. Remove Duplicates from Sorted Array | [Go]({{< relref "/ChapterFour/0026.Remove-Duplicates-from-Sorted-Array.md" >}})| Easy | O(n)| O(1)||
|
||||
|27. Remove Element | [Go]({{< relref "/ChapterFour/0027.Remove-Element.md" >}})| Easy | O(n)| O(1)||
|
||||
|28. Implement strStr() | [Go]({{< relref "/ChapterFour/0028.Implement-strStr.md" >}})| Easy | O(n)| O(1)||
|
||||
|30. Substring with Concatenation of All Words | [Go]({{< relref "/ChapterFour/0030.Substring-with-Concatenation-of-All-Words.md" >}})| Hard | O(n)| O(n)|❤️|
|
||||
|42. Trapping Rain Water | [Go]({{< relref "/ChapterFour/0042.Trapping-Rain-Water.md" >}})| Hard | O(n)| O(1)|❤️|
|
||||
|61. Rotate List | [Go]({{< relref "/ChapterFour/0061.Rotate-List.md" >}})| Medium | O(n)| O(1)||
|
||||
|75. Sort Colors | [Go]({{< relref "/ChapterFour/0075.Sort-Colors.md" >}})| Medium| O(n)| O(1)|❤️|
|
||||
|76. Minimum Window Substring | [Go]({{< relref "/ChapterFour/0076.Minimum-Window-Substring.md" >}})| Hard | O(n)| O(n)|❤️|
|
||||
|80. Remove Duplicates from Sorted Array II | [Go]({{< relref "/ChapterFour/0080.Remove-Duplicates-from-Sorted-Array-II.md" >}})| Medium | O(n)| O(1||
|
||||
|86. Partition List | [Go]({{< relref "/ChapterFour/0086.Partition-List.md" >}})| Medium | O(n)| O(1)|❤️|
|
||||
|88. Merge Sorted Array | [Go]({{< relref "/ChapterFour/0088.Merge-Sorted-Array.md" >}})| Easy | O(n)| O(1)|❤️|
|
||||
|125. Valid Palindrome | [Go]({{< relref "/ChapterFour/0125.Valid-Palindrome.md" >}})| Easy | O(n)| O(1)||
|
||||
|141. Linked List Cycle | [Go]({{< relref "/ChapterFour/0141.Linked-List-Cycle.md" >}})| Easy | O(n)| O(1)|❤️|
|
||||
|142. Linked List Cycle II | [Go]({{< relref "/ChapterFour/0142.Linked-List-Cycle-II.md" >}})| Medium | O(n)| O(1)|❤️|
|
||||
|167. Two Sum II - Input array is sorted | [Go]({{< relref "/ChapterFour/0167.Two-Sum-II---Input-array-is-sorted.md" >}})| Easy | O(n)| O(1)||
|
||||
|209. Minimum Size Subarray Sum | [Go]({{< relref "/ChapterFour/0209.Minimum-Size-Subarray-Sum.md" >}})| Medium | O(n)| O(1)||
|
||||
|234. Palindrome Linked List | [Go]({{< relref "/ChapterFour/0234.Palindrome-Linked-List.md" >}})| Easy | O(n)| O(1)||
|
||||
|283. Move Zeroes | [Go]({{< relref "/ChapterFour/0283.Move-Zeroes.md" >}})| Easy | O(n)| O(1)||
|
||||
|287. Find the Duplicate Number | [Go]({{< relref "/ChapterFour/0287.Find-the-Duplicate-Number.md" >}})| Easy | O(n)| O(1)|❤️|
|
||||
|344. Reverse String | [Go]({{< relref "/ChapterFour/0344.Reverse-String.md" >}})| Easy | O(n)| O(1)||
|
||||
|345. Reverse Vowels of a String | [Go]({{< relref "/ChapterFour/0345.Reverse-Vowels-of-a-String.md" >}})| Easy | O(n)| O(1)||
|
||||
|349. Intersection of Two Arrays | [Go]({{< relref "/ChapterFour/0349.Intersection-of-Two-Arrays.md" >}})| Easy | O(n)| O(n) ||
|
||||
|350. Intersection of Two Arrays II | [Go]({{< relref "/ChapterFour/0350.Intersection-of-Two-Arrays-II.md" >}})| Easy | O(n)| O(n) ||
|
||||
|424. Longest Repeating Character Replacement | [Go]({{< relref "/ChapterFour/0424.Longest-Repeating-Character-Replacement.md" >}})| Medium | O(n)| O(1) ||
|
||||
|524. Longest Word in Dictionary through Deleting | [Go]({{< relref "/ChapterFour/0524.Longest-Word-in-Dictionary-through-Deleting.md" >}})| Medium | O(n)| O(1) ||
|
||||
|532. K-diff Pairs in an Array | [Go]({{< relref "/ChapterFour/0532.K-diff-Pairs-in-an-Array.md" >}})| Easy | O(n)| O(n)||
|
||||
|567. Permutation in String | [Go]({{< relref "/ChapterFour/0567.Permutation-in-String.md" >}})| Medium | O(n)| O(1)|❤️|
|
||||
|713. Subarray Product Less Than K | [Go]({{< relref "/ChapterFour/0713.Subarray-Product-Less-Than-K.md" >}})| Medium | O(n)| O(1)||
|
||||
|763. Partition Labels | [Go]({{< relref "/ChapterFour/0763.Partition-Labels.md" >}})| Medium | O(n)| O(1)|❤️|
|
||||
|826. Most Profit Assigning Work | [Go]({{< relref "/ChapterFour/0826.Most-Profit-Assigning-Work.md" >}})| Medium | O(n log n)| O(n)||
|
||||
|828. Count Unique Characters of All Substrings of a Given String | [Go]({{< relref "/ChapterFour/0828.Count-Unique-Characters-of-All-Substrings-of-a-Given-String.md" >}})| Hard | O(n)| O(1)|❤️|
|
||||
|838. Push Dominoes | [Go]({{< relref "/ChapterFour/0838.Push-Dominoes.md" >}})| Medium | O(n)| O(n)||
|
||||
|844. Backspace String Compare | [Go]({{< relref "/ChapterFour/0844.Backspace-String-Compare.md" >}})| Easy | O(n)| O(n) ||
|
||||
|845. Longest Mountain in Array | [Go]({{< relref "/ChapterFour/0845.Longest-Mountain-in-Array.md" >}})| Medium | O(n)| O(1) ||
|
||||
|881. Boats to Save People | [Go]({{< relref "/ChapterFour/0881.Boats-to-Save-People.md" >}})| Medium | O(n log n)| O(1) ||
|
||||
|904. Fruit Into Baskets | [Go]({{< relref "/ChapterFour/0904.Fruit-Into-Baskets.md" >}})| Medium | O(n log n)| O(1) ||
|
||||
|923. 3Sum With Multiplicity | [Go]({{< relref "/ChapterFour/0923.3Sum-With-Multiplicity.md" >}})| Medium | O(n^2)| O(n) ||
|
||||
|925. Long Pressed Name | [Go]({{< relref "/ChapterFour/0925.Long-Pressed-Name.md" >}})| Easy | O(n)| O(1)||
|
||||
|930. Binary Subarrays With Sum | [Go]({{< relref "/ChapterFour/0930.Binary-Subarrays-With-Sum.md" >}})| Medium | O(n)| O(n) |❤️|
|
||||
|977. Squares of a Sorted Array | [Go]({{< relref "/ChapterFour/0977.Squares-of-a-Sorted-Array.md" >}})| Easy | O(n)| O(1)||
|
||||
|986. Interval List Intersections | [Go]({{< relref "/ChapterFour/0986.Interval-List-Intersections.md" >}})| Medium | O(n)| O(1)||
|
||||
|992. Subarrays with K Different Integers | [Go]({{< relref "/ChapterFour/0992.Subarrays-with-K-Different-Integers.md" >}})| Hard | O(n)| O(n)|❤️|
|
||||
|1004. Max Consecutive Ones III | [Go]({{< relref "/ChapterFour/1004.Max-Consecutive-Ones-III.md" >}})| Medium | O(n)| O(1) ||
|
||||
|1093. Statistics from a Large Sample | [Go]({{< relref "/ChapterFour/1093.Statistics-from-a-Large-Sample.md" >}})| Medium | O(n)| O(1) ||
|
18
ctl/meta/Union_Find
Normal file
18
ctl/meta/Union_Find
Normal file
@ -0,0 +1,18 @@
|
||||
|128. Longest Consecutive Sequence | [Go]({{< relref "/ChapterFour/0128.Longest-Consecutive-Sequence.md" >}})| Hard | O(n)| O(n)|❤️|
|
||||
|130. Surrounded Regions | [Go]({{< relref "/ChapterFour/0130.Surrounded-Regions.md" >}})| Medium | O(m\*n)| O(m\*n)||
|
||||
|200. Number of Islands | [Go]({{< relref "/ChapterFour/0200.Number-of-Islands.md" >}})| Medium | O(m\*n)| O(m\*n)||
|
||||
|399. Evaluate Division | [Go]({{< relref "/ChapterFour/0399.Evaluate-Division.md" >}})| Medium | O(n)| O(n)||
|
||||
|547. Number of Provinces | [Go]({{< relref "/ChapterFour/0547.Number-of-Provinces.md" >}})| Medium | O(n^2)| O(n)||
|
||||
|684. Redundant Connection | [Go]({{< relref "/ChapterFour/0684.Redundant-Connection.md" >}})| Medium | O(n)| O(n)||
|
||||
|685. Redundant Connection II | [Go]({{< relref "/ChapterFour/0685.Redundant-Connection-II.md" >}})| Hard | O(n)| O(n)||
|
||||
|721. Accounts Merge | [Go]({{< relref "/ChapterFour/0721.Accounts-Merge.md" >}})| Medium | O(n)| O(n)|❤️|
|
||||
|765. Couples Holding Hands | [Go]({{< relref "/ChapterFour/0765.Couples-Holding-Hands.md" >}})| Hard | O(n)| O(n)|❤️|
|
||||
|778. Swim in Rising Water | [Go]({{< relref "/ChapterFour/0778.Swim-in-Rising-Water.md" >}})| Hard | O(n^2)| O(n)|❤️|
|
||||
|803. Bricks Falling When Hit | [Go]({{< relref "/ChapterFour/0803.Bricks-Falling-When-Hit.md" >}})| Hard | O(n^2)| O(n)|❤️|
|
||||
|839. Similar String Groups | [Go]({{< relref "/ChapterFour/0839.Similar-String-Groups.md" >}})| Hard | O(n^2)| O(n)||
|
||||
|924. Minimize Malware Spread | [Go]({{< relref "/ChapterFour/0924.Minimize-Malware-Spread.md" >}})| Hard | O(m\*n)| O(n)||
|
||||
|928. Minimize Malware Spread II | [Go]({{< relref "/ChapterFour/0928.Minimize-Malware-Spread-II.md" >}})| Hard | O(m\*n)| O(n)|❤️|
|
||||
|947. Most Stones Removed with Same Row or Column | [Go]({{< relref "/ChapterFour/0947.Most-Stones-Removed-with-Same-Row-or-Column.md" >}})| Medium | O(n)| O(n)||
|
||||
|952. Largest Component Size by Common Factor | [Go]({{< relref "/ChapterFour/0952.Largest-Component-Size-by-Common-Factor.md" >}})| Hard | O(n)| O(n)|❤️|
|
||||
|959. Regions Cut By Slashes | [Go]({{< relref "/ChapterFour/0959.Regions-Cut-By-Slashes.md" >}})| Medium | O(n^2)| O(n^2)|❤️|
|
||||
|990. Satisfiability of Equality Equations | [Go]({{< relref "/ChapterFour/0990.Satisfiability-of-Equality-Equations.md" >}})| Medium | O(n)| O(n)||
|
2
ctl/meta/meta
Normal file
2
ctl/meta/meta
Normal file
@ -0,0 +1,2 @@
|
||||
| Title | Solution | Difficulty | Time | Space |收藏|
|
||||
| ----- | :--------: | :----------: | :----: | :-----: | :-----: |
|
223
ctl/pdf.go
Normal file
223
ctl/pdf.go
Normal file
@ -0,0 +1,223 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var (
|
||||
cleanString1 = "{{< columns >}}"
|
||||
cleanString2 = "<--->"
|
||||
cleanString3 = "{{< /columns >}}"
|
||||
cleanString4 = "<img src=\"https://books.halfrost.com/leetcode/logo.png\" alt=\"logo\" height=\"600\" align=\"right\" style=\"padding-left: 30px;\"/>"
|
||||
pdfPreface = `<img src="https://books.halfrost.com/leetcode/logo.png" alt="logo" heigth="1300px" align="center"/>
|
||||
|
||||
|
||||
# 说明
|
||||
|
||||
此版本是 https://books.halfrost.com/leetcode 网页的离线版,由于网页版实时会更新,所以此 PDF 版难免会有一些排版或者错别字。如果读者遇到了,可以到网页版相应页面,点击页面 edit 按钮,提交 pr 进行更改。此 PDF 版本号是 V%v.%v.%v。PDF 永久更新地址是 https://github.com/halfrost/leetcode-go/releases/,以版本号区分不同版本。笔者还是强烈推荐看在线版,有任何错误都会立即更新。如果觉得此书对刷题有一点点帮助,可以给此书点一个 star,鼓励一下笔者早点更新更多题解。
|
||||
|
||||
> 版本号说明,V%v.%v.%v,%v 是大版本号,%v 代表当前题解中有几百题,目前是 %v 题,所以第二个版本号是 %v,%v 代表当前题解中有几十题,目前是 %v 题,所以第三个版本号是 %v 。
|
||||
|
||||
# 目录
|
||||
|
||||
[toc]
|
||||
|
||||
`
|
||||
|
||||
majorVersion = 1
|
||||
midVersion = 0
|
||||
lastVersion = 0
|
||||
totalSolutions = 0
|
||||
)
|
||||
|
||||
func newPDFCommand() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "pdf",
|
||||
Short: "PDF related commands",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
generatePDF()
|
||||
},
|
||||
}
|
||||
// cmd.Flags().StringVar(&alias, "alias", "", "alias")
|
||||
// cmd.Flags().StringVar(&appId, "appid", "", "appid")
|
||||
return cmd
|
||||
}
|
||||
|
||||
func generatePDF() {
|
||||
var (
|
||||
pdf, tmp []byte
|
||||
err error
|
||||
)
|
||||
// 先删除 pre-next
|
||||
delPreNext()
|
||||
|
||||
chapterFourFileOrder, _ := LoadChapterFourDir()
|
||||
totalSolutions = len(chapterFourFileOrder)
|
||||
midVersion = totalSolutions / 100
|
||||
lastVersion = totalSolutions % 100
|
||||
fmt.Printf("[当前的版本号是 V%v.%v.%v]\n", majorVersion, midVersion, lastVersion)
|
||||
// 删除原始文档中的头部,并创建临时文件夹
|
||||
prepare(fmt.Sprintf("../PDF v%v.%v.%v.md", majorVersion, midVersion, lastVersion))
|
||||
// PDF 前言
|
||||
pdf = append(pdf, []byte(fmt.Sprintf(pdfPreface, majorVersion, midVersion, lastVersion, majorVersion, midVersion, lastVersion, majorVersion, midVersion, totalSolutions, midVersion, lastVersion, totalSolutions, lastVersion))...)
|
||||
// PDF 第一章
|
||||
tmp, err = loadChapter(chapterOneFileOrder, "./pdftemp", "ChapterOne")
|
||||
pdf = append(pdf, tmp...)
|
||||
// PDF 第二章
|
||||
tmp, err = loadChapter(chapterTwoFileOrder, "./pdftemp", "ChapterTwo")
|
||||
pdf = append(pdf, tmp...)
|
||||
// PDF 第三章
|
||||
tmp, err = loadChapter(chapterThreeFileOrder, "./pdftemp", "ChapterThree")
|
||||
pdf = append(pdf, tmp...)
|
||||
// PDF 第四章
|
||||
tmp, err = LoadFile("./pdftemp/ChapterFour/_index.md")
|
||||
pdf = append(pdf, tmp...)
|
||||
tmp, err = loadChapter(chapterFourFileOrder, "../website/content", "ChapterFour")
|
||||
pdf = append(pdf, tmp...)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
// 生成 PDF
|
||||
WriteFile(fmt.Sprintf("../PDF v%v.%v.%v.md", majorVersion, midVersion, lastVersion), pdf)
|
||||
// 还原现场
|
||||
addPreNext()
|
||||
DestoryDir("./pdftemp")
|
||||
}
|
||||
|
||||
func loadChapter(order []string, path, chapter string) ([]byte, error) {
|
||||
var (
|
||||
res, tmp []byte
|
||||
err error
|
||||
)
|
||||
for index, v := range order {
|
||||
if chapter == "ChapterOne" && index == 0 {
|
||||
// 清理不支持的特殊 MarkDown 语法
|
||||
tmp, err = clean(fmt.Sprintf("%v/%v/%v.md", path, chapter, v))
|
||||
} else {
|
||||
if chapter == "ChapterFour" {
|
||||
if v[4] == '.' {
|
||||
num, err := strconv.Atoi(v[:4])
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
tmp, err = LoadFile(fmt.Sprintf("%v/%v/%v/%v.md", path, chapter, GetChpaterFourFileNum(num), v))
|
||||
}
|
||||
} else {
|
||||
tmp, err = LoadFile(fmt.Sprintf("%v/%v/%v.md", path, chapter, v))
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return []byte{}, err
|
||||
}
|
||||
res = append(res, tmp...)
|
||||
}
|
||||
return res, err
|
||||
}
|
||||
|
||||
func prepare(path string) {
|
||||
err := os.Remove(path)
|
||||
if err != nil {
|
||||
fmt.Println("pdf 还没有创建")
|
||||
fmt.Println(err)
|
||||
}
|
||||
fmt.Println("pdf 删除成功,开始构建全新版本")
|
||||
|
||||
err = os.MkdirAll("./pdftemp/ChapterOne", os.ModePerm)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
for _, v := range chapterOneFileOrder {
|
||||
removeHeader(fmt.Sprintf("../website/content/ChapterOne/%v.md", v), fmt.Sprintf("./pdftemp/ChapterOne/%v.md", v), 5)
|
||||
}
|
||||
|
||||
err = os.MkdirAll("./pdftemp/ChapterTwo", os.ModePerm)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
// 生成外部链接的 ChapterTwo
|
||||
buildChapterTwo(false)
|
||||
CopyFile("./pdftemp/ChapterTwo/_index.md", "../website/content/ChapterTwo/_index.md")
|
||||
|
||||
for _, v := range chapterTwoFileOrder {
|
||||
removeHeader(fmt.Sprintf("./pdftemp/ChapterTwo/%v.md", v), fmt.Sprintf("./pdftemp/ChapterTwo/%v.md", v), 5)
|
||||
}
|
||||
|
||||
err = os.MkdirAll("./pdftemp/ChapterThree", os.ModePerm)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
for _, v := range chapterThreeFileOrder {
|
||||
removeHeader(fmt.Sprintf("../website/content/ChapterThree/%v.md", v), fmt.Sprintf("./pdftemp/ChapterThree/%v.md", v), 5)
|
||||
}
|
||||
|
||||
err = os.MkdirAll("./pdftemp/ChapterFour", os.ModePerm)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
removeHeader(fmt.Sprintf("../website/content/ChapterFour/_index.md"), fmt.Sprintf("./pdftemp/ChapterFour/_index.md"), 5)
|
||||
}
|
||||
|
||||
func clean(filePath string) ([]byte, error) {
|
||||
f, err := os.OpenFile(filePath, os.O_RDONLY, 0644)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer f.Close()
|
||||
reader, output := bufio.NewReader(f), []byte{}
|
||||
for {
|
||||
line, _, err := reader.ReadLine()
|
||||
if err != nil {
|
||||
if err == io.EOF {
|
||||
return output, nil
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
if ok, _ := regexp.Match(cleanString1, line); ok {
|
||||
reg := regexp.MustCompile(cleanString1)
|
||||
newByte := reg.ReplaceAll(line, []byte(""))
|
||||
output = append(output, newByte...)
|
||||
output = append(output, []byte("\n")...)
|
||||
} else if ok, _ := regexp.Match(cleanString2, line); ok {
|
||||
reg := regexp.MustCompile(cleanString2)
|
||||
newByte := reg.ReplaceAll(line, []byte(""))
|
||||
output = append(output, newByte...)
|
||||
output = append(output, []byte("\n")...)
|
||||
} else if ok, _ := regexp.Match(cleanString3, line); ok {
|
||||
reg := regexp.MustCompile(cleanString3)
|
||||
newByte := reg.ReplaceAll(line, []byte(""))
|
||||
output = append(output, newByte...)
|
||||
output = append(output, []byte("\n")...)
|
||||
} else if ok, _ := regexp.Match(cleanString4, line); ok {
|
||||
reg := regexp.MustCompile(cleanString4)
|
||||
newByte := reg.ReplaceAll(line, []byte(""))
|
||||
output = append(output, newByte...)
|
||||
output = append(output, []byte("\n")...)
|
||||
} else {
|
||||
output = append(output, line...)
|
||||
output = append(output, []byte("\n")...)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func removeHeader(path, newPath string, lineNumber int) {
|
||||
file, err := ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
info, _ := os.Stat(path)
|
||||
mode := info.Mode()
|
||||
array := strings.Split(string(file), "\n")
|
||||
array = array[lineNumber:]
|
||||
ioutil.WriteFile(newPath, []byte(strings.Join(array, "\n")), mode)
|
||||
//fmt.Println("remove line successful")
|
||||
}
|
36
ctl/rangking.go
Normal file
36
ctl/rangking.go
Normal file
@ -0,0 +1,36 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// getRanking 让这个方法优雅一点
|
||||
func getRanking() int {
|
||||
// 获取网页数据
|
||||
URL := fmt.Sprintf("https://leetcode.com/%s/", getConfig().Username)
|
||||
data := getRaw(URL)
|
||||
str := string(data)
|
||||
// 通过不断裁剪 str 获取排名信息
|
||||
fmt.Println(str)
|
||||
i := strings.Index(str, "ng-init")
|
||||
j := i + strings.Index(str[i:], "ng-cloak")
|
||||
str = str[i:j]
|
||||
i = strings.Index(str, "(")
|
||||
j = strings.Index(str, ")")
|
||||
str = str[i:j]
|
||||
// fmt.Println("2\n", str)
|
||||
strs := strings.Split(str, ",")
|
||||
str = strs[6]
|
||||
// fmt.Println("1\n", str)
|
||||
i = strings.Index(str, "'")
|
||||
j = 2 + strings.Index(str[2:], "'")
|
||||
// fmt.Println("0\n", str)
|
||||
str = str[i+1 : j]
|
||||
r, err := strconv.Atoi(str)
|
||||
if err != nil {
|
||||
fmt.Printf("无法把 %s 转换成数字Ranking", str)
|
||||
}
|
||||
return r
|
||||
}
|
27
ctl/refresh.go
Normal file
27
ctl/refresh.go
Normal file
@ -0,0 +1,27 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func newRefresh() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "refresh",
|
||||
Short: "Refresh all document",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
refresh()
|
||||
},
|
||||
}
|
||||
// cmd.Flags().StringVar(&alias, "alias", "", "alias")
|
||||
// cmd.Flags().StringVar(&appId, "appid", "", "appid")
|
||||
return cmd
|
||||
}
|
||||
|
||||
func refresh() {
|
||||
//buildBookMenu()
|
||||
copyLackFile()
|
||||
delPreNext()
|
||||
buildREADME()
|
||||
buildChapterTwo(true)
|
||||
addPreNext()
|
||||
}
|
365
ctl/render.go
Normal file
365
ctl/render.go
Normal file
@ -0,0 +1,365 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var (
|
||||
chapterTwoList = []string{"Array", "String", "Two Pointers", "Linked List", "Stack", "Tree", "Dynamic Programming", "Backtracking", "Depth First Search", "Breadth First Search",
|
||||
"Binary Search", "Math", "Hash Table", "Sorting", "Bit Manipulation", "Union Find", "Sliding Window", "Segment Tree", "Binary Indexed Tree"}
|
||||
chapterTwoFileName = []string{"Array", "String", "Two_Pointers", "Linked_List", "Stack", "Tree", "Dynamic_Programming", "Backtracking", "Depth_First_Search", "Breadth_First_Search",
|
||||
"Binary_Search", "Math", "Hash_Table", "Sorting", "Bit_Manipulation", "Union_Find", "Sliding_Window", "Segment_Tree", "Binary_Indexed_Tree"}
|
||||
chapterTwoSlug = []string{"array", "string", "two-pointers", "linked-list", "stack", "tree", "dynamic-programming", "backtracking", "depth-first-search", "breadth-first-search",
|
||||
"binary-search", "math", "hash-table", "sorting", "bit-manipulation", "union-find", "sliding-window", "segment-tree", "binary-indexed-tree"}
|
||||
)
|
||||
|
||||
func newBuildCommand() *cobra.Command {
|
||||
mc := &cobra.Command{
|
||||
Use: "build <subcommand>",
|
||||
Short: "Build doc related commands",
|
||||
}
|
||||
//mc.PersistentFlags().StringVar(&logicEndpoint, "endpoint", "localhost:5880", "endpoint of logic service")
|
||||
mc.AddCommand(
|
||||
newBuildREADME(),
|
||||
newBuildChapterTwo(),
|
||||
// newBuildMenu(),
|
||||
)
|
||||
return mc
|
||||
}
|
||||
|
||||
func newBuildREADME() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "readme",
|
||||
Short: "Build readme.md commands",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
buildREADME()
|
||||
},
|
||||
}
|
||||
// cmd.Flags().StringVar(&alias, "alias", "", "alias")
|
||||
// cmd.Flags().StringVar(&appId, "appid", "", "appid")
|
||||
return cmd
|
||||
}
|
||||
|
||||
func newBuildChapterTwo() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "chapter-two",
|
||||
Short: "Build Chapter Two commands",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
buildChapterTwo(true)
|
||||
},
|
||||
}
|
||||
// cmd.Flags().StringVar(&alias, "alias", "", "alias")
|
||||
// cmd.Flags().StringVar(&appId, "appid", "", "appid")
|
||||
return cmd
|
||||
}
|
||||
|
||||
func newBuildMenu() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "menu",
|
||||
Short: "Build Menu commands",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
buildBookMenu()
|
||||
},
|
||||
}
|
||||
// cmd.Flags().StringVar(&alias, "alias", "", "alias")
|
||||
// cmd.Flags().StringVar(&appId, "appid", "", "appid")
|
||||
return cmd
|
||||
}
|
||||
|
||||
func buildREADME() {
|
||||
var (
|
||||
problems []StatStatusPairs
|
||||
lpa LeetCodeProblemAll
|
||||
info UserInfo
|
||||
)
|
||||
// 请求所有题目信息
|
||||
body := getProblemAllList()
|
||||
problemsMap, optimizingIds := map[int]StatStatusPairs{}, []int{}
|
||||
err := json.Unmarshal(body, &lpa)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
//writeFile("leetcode_problem.json", body)
|
||||
|
||||
// 拼凑 README 需要渲染的数据
|
||||
problems = lpa.StatStatusPairs
|
||||
info = ConvertUserInfoModel(lpa)
|
||||
for _, v := range problems {
|
||||
problemsMap[int(v.Stat.FrontendQuestionID)] = v
|
||||
}
|
||||
mdrows := ConvertMdModelFromSsp(problems)
|
||||
sort.Sort(SortByQuestionID(mdrows))
|
||||
solutionIds, _, try := LoadSolutionsDir()
|
||||
GenerateMdRows(solutionIds, mdrows)
|
||||
info.EasyTotal, info.MediumTotal, info.HardTotal, info.OptimizingEasy, info.OptimizingMedium, info.OptimizingHard, optimizingIds = statisticalData(problemsMap, solutionIds)
|
||||
omdrows := ConvertMdModelFromIds(problemsMap, optimizingIds)
|
||||
sort.Sort(SortByQuestionID(omdrows))
|
||||
|
||||
// 按照模板渲染 README
|
||||
res, err := renderReadme("./template/template.markdown", len(solutionIds), try, Mdrows{Mdrows: mdrows}, Mdrows{Mdrows: omdrows}, info)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
WriteFile("../README.md", res)
|
||||
fmt.Println("write file successful")
|
||||
//makeReadmeFile(mds)
|
||||
}
|
||||
|
||||
func renderReadme(filePath string, total, try int, mdrows, omdrows Mdrows, user UserInfo) ([]byte, error) {
|
||||
f, err := os.OpenFile(filePath, os.O_RDONLY, 0644)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer f.Close()
|
||||
reader, output := bufio.NewReader(f), []byte{}
|
||||
|
||||
for {
|
||||
line, _, err := reader.ReadLine()
|
||||
if err != nil {
|
||||
if err == io.EOF {
|
||||
return output, nil
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
if ok, _ := regexp.Match("{{.AvailableTable}}", line); ok {
|
||||
reg := regexp.MustCompile("{{.AvailableTable}}")
|
||||
newByte := reg.ReplaceAll(line, []byte(mdrows.AvailableTable()))
|
||||
output = append(output, newByte...)
|
||||
output = append(output, []byte("\n")...)
|
||||
} else if ok, _ := regexp.Match("{{.TotalNum}}", line); ok {
|
||||
reg := regexp.MustCompile("{{.TotalNum}}")
|
||||
newByte := reg.ReplaceAll(line, []byte(fmt.Sprintf("以下已经收录了 %v 道题的题解,还有 %v 道题在尝试优化到 beats 100%%", total, try)))
|
||||
output = append(output, newByte...)
|
||||
output = append(output, []byte("\n")...)
|
||||
} else if ok, _ := regexp.Match("{{.PersonalData}}", line); ok {
|
||||
reg := regexp.MustCompile("{{.PersonalData}}")
|
||||
newByte := reg.ReplaceAll(line, []byte(user.PersonalData()))
|
||||
output = append(output, newByte...)
|
||||
output = append(output, []byte("\n")...)
|
||||
} else if ok, _ := regexp.Match("{{.OptimizingTable}}", line); ok {
|
||||
reg := regexp.MustCompile("{{.OptimizingTable}}")
|
||||
newByte := reg.ReplaceAll(line, []byte(fmt.Sprintf("以下 %v 道题还需要优化到 100%% 的题目列表\n\n%v", (user.OptimizingEasy+user.OptimizingMedium+user.OptimizingHard), omdrows.AvailableTable())))
|
||||
output = append(output, newByte...)
|
||||
output = append(output, []byte("\n")...)
|
||||
} else {
|
||||
output = append(output, line...)
|
||||
output = append(output, []byte("\n")...)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// internal: true 渲染的链接都是 hugo 内部链接,用户生成 hugo web
|
||||
//
|
||||
// false 渲染的链接是外部 HTTPS 链接,用于生成 PDF
|
||||
func buildChapterTwo(internal bool) {
|
||||
var (
|
||||
gr GraphQLResp
|
||||
questions []Question
|
||||
count int
|
||||
)
|
||||
for index, tag := range chapterTwoSlug {
|
||||
body := getTagProblemList(tag)
|
||||
// fmt.Printf("%v\n", string(body))
|
||||
err := json.Unmarshal(body, &gr)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
questions = gr.Data.TopicTag.Questions
|
||||
mdrows := ConvertMdModelFromQuestions(questions)
|
||||
sort.Sort(SortByQuestionID(mdrows))
|
||||
solutionIds, _, _ := LoadSolutionsDir()
|
||||
tl, err := loadMetaData(fmt.Sprintf("./meta/%v", chapterTwoFileName[index]))
|
||||
if err != nil {
|
||||
fmt.Printf("err = %v\n", err)
|
||||
}
|
||||
tls := GenerateTagMdRows(solutionIds, tl, mdrows, internal)
|
||||
//fmt.Printf("tls = %v\n", tls)
|
||||
// 按照模板渲染 README
|
||||
res, err := renderChapterTwo(fmt.Sprintf("./template/%v.md", chapterTwoFileName[index]), TagLists{TagLists: tls})
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
if internal {
|
||||
WriteFile(fmt.Sprintf("../website/content/ChapterTwo/%v.md", chapterTwoFileName[index]), res)
|
||||
} else {
|
||||
WriteFile(fmt.Sprintf("./pdftemp/ChapterTwo/%v.md", chapterTwoFileName[index]), res)
|
||||
}
|
||||
|
||||
count++
|
||||
}
|
||||
fmt.Printf("write %v files successful", count)
|
||||
}
|
||||
|
||||
func loadMetaData(filePath string) (map[int]TagList, error) {
|
||||
f, err := os.OpenFile(filePath, os.O_RDONLY, 0644)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer f.Close()
|
||||
reader, metaMap := bufio.NewReader(f), map[int]TagList{}
|
||||
|
||||
for {
|
||||
line, _, err := reader.ReadLine()
|
||||
if err != nil {
|
||||
if err == io.EOF {
|
||||
return metaMap, nil
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
s := strings.Split(string(line), "|")
|
||||
v, _ := strconv.Atoi(strings.Split(s[1], ".")[0])
|
||||
// v[0] 是题号,s[4] time, s[5] space, s[6] favorite
|
||||
metaMap[v] = TagList{
|
||||
FrontendQuestionID: int32(v),
|
||||
Acceptance: "",
|
||||
Difficulty: "",
|
||||
TimeComplexity: s[4],
|
||||
SpaceComplexity: s[5],
|
||||
Favorite: s[6],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func renderChapterTwo(filePath string, tls TagLists) ([]byte, error) {
|
||||
f, err := os.OpenFile(filePath, os.O_RDONLY, 0644)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer f.Close()
|
||||
reader, output := bufio.NewReader(f), []byte{}
|
||||
|
||||
for {
|
||||
line, _, err := reader.ReadLine()
|
||||
if err != nil {
|
||||
if err == io.EOF {
|
||||
return output, nil
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
if ok, _ := regexp.Match("{{.AvailableTagTable}}", line); ok {
|
||||
reg := regexp.MustCompile("{{.AvailableTagTable}}")
|
||||
newByte := reg.ReplaceAll(line, []byte(tls.AvailableTagTable()))
|
||||
output = append(output, newByte...)
|
||||
output = append(output, []byte("\n")...)
|
||||
} else {
|
||||
output = append(output, line...)
|
||||
output = append(output, []byte("\n")...)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func buildBookMenu() {
|
||||
copyLackFile()
|
||||
// 按照模板重新渲染 Menu
|
||||
res, err := renderBookMenu("./template/menu.md")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
WriteFile("../website/content/menu/index.md", res)
|
||||
fmt.Println("generate Menu successful")
|
||||
}
|
||||
|
||||
// 拷贝 leetcode 目录下的题解 README 文件至第四章对应文件夹中
|
||||
func copyLackFile() {
|
||||
solutionIds, soName, _ := LoadSolutionsDir()
|
||||
_, ch4Ids := LoadChapterFourDir()
|
||||
|
||||
needCopy := []string{}
|
||||
for i := 0; i < len(solutionIds); i++ {
|
||||
if BinarySearch(ch4Ids, solutionIds[i]) == -1 {
|
||||
needCopy = append(needCopy, soName[i])
|
||||
}
|
||||
}
|
||||
if len(needCopy) > 0 {
|
||||
fmt.Printf("有 %v 道题需要拷贝到第四章中\n", len(needCopy))
|
||||
for i := 0; i < len(needCopy); i++ {
|
||||
if needCopy[i][4] == '.' {
|
||||
tmp, err := strconv.Atoi(needCopy[i][:4])
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
err = os.MkdirAll(fmt.Sprintf("../website/content/ChapterFour/%v", GetChpaterFourFileNum(tmp)), os.ModePerm)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
CopyFile(fmt.Sprintf("../website/content/ChapterFour/%v/%v.md", GetChpaterFourFileNum(tmp), needCopy[i]), fmt.Sprintf("../leetcode/%v/README.md", needCopy[i]))
|
||||
CopyFile(fmt.Sprintf("../website/content/ChapterFour/%v/_index.md", GetChpaterFourFileNum(tmp)), "./template/collapseSection.md")
|
||||
}
|
||||
}
|
||||
} else {
|
||||
fmt.Printf("【第四章没有需要添加的题解,已经完整了】\n")
|
||||
}
|
||||
}
|
||||
|
||||
func generateMenu() string {
|
||||
res := ""
|
||||
res += menuLine(chapterOneMenuOrder, "ChapterOne")
|
||||
res += menuLine(chapterTwoFileOrder, "ChapterTwo")
|
||||
res += menuLine(chapterThreeFileOrder, "ChapterThree")
|
||||
chapterFourFileOrder, _ := getChapterFourFileOrder()
|
||||
res += menuLine(chapterFourFileOrder, "ChapterFour")
|
||||
return res
|
||||
}
|
||||
|
||||
func menuLine(order []string, chapter string) string {
|
||||
res := ""
|
||||
for i := 0; i < len(order); i++ {
|
||||
if i == 1 && chapter == "ChapterOne" {
|
||||
res += fmt.Sprintf(" - [%v]({{< relref \"/%v/%v\" >}})\n", chapterMap[chapter][order[i]], chapter, order[i])
|
||||
continue
|
||||
}
|
||||
if i == 0 {
|
||||
res += fmt.Sprintf("- [%v]({{< relref \"/%v/%v.md\" >}})\n", chapterMap[chapter][order[i]], chapter, order[i])
|
||||
} else {
|
||||
if chapter == "ChapterFour" {
|
||||
res += fmt.Sprintf(" - [%v]({{< relref \"/%v/%v.md\" >}})\n", order[i], chapter, order[i])
|
||||
} else {
|
||||
res += fmt.Sprintf(" - [%v]({{< relref \"/%v/%v.md\" >}})\n", chapterMap[chapter][order[i]], chapter, order[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func renderBookMenu(filePath string) ([]byte, error) {
|
||||
f, err := os.OpenFile(filePath, os.O_RDONLY, 0644)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer f.Close()
|
||||
reader, output := bufio.NewReader(f), []byte{}
|
||||
|
||||
for {
|
||||
line, _, err := reader.ReadLine()
|
||||
if err != nil {
|
||||
if err == io.EOF {
|
||||
return output, nil
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
if ok, _ := regexp.Match("{{.BookMenu}}", line); ok {
|
||||
reg := regexp.MustCompile("{{.BookMenu}}")
|
||||
newByte := reg.ReplaceAll(line, []byte(generateMenu()))
|
||||
output = append(output, newByte...)
|
||||
output = append(output, []byte("\n")...)
|
||||
} else {
|
||||
output = append(output, line...)
|
||||
output = append(output, []byte("\n")...)
|
||||
}
|
||||
}
|
||||
}
|
110
ctl/request.go
Normal file
110
ctl/request.go
Normal file
@ -0,0 +1,110 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
|
||||
"github.com/mozillazg/request"
|
||||
)
|
||||
|
||||
const (
|
||||
// AllProblemURL define
|
||||
AllProblemURL = "https://leetcode.com/api/problems/all/"
|
||||
// QraphqlURL define
|
||||
QraphqlURL = "https://leetcode.com/graphql"
|
||||
// LoginPageURL define
|
||||
LoginPageURL = "https://leetcode.com/accounts/login/"
|
||||
// AlgorithmsURL define
|
||||
AlgorithmsURL = "https://leetcode.com/api/problems/Algorithms/"
|
||||
|
||||
// ArrayProblemURL define
|
||||
ArrayProblemURL = "https://leetcode.com/tag/array/"
|
||||
)
|
||||
|
||||
var req *request.Request
|
||||
|
||||
func newReq() *request.Request {
|
||||
if req == nil {
|
||||
req = signin()
|
||||
}
|
||||
return req
|
||||
}
|
||||
|
||||
func signin() *request.Request {
|
||||
cfg := getConfig()
|
||||
req := request.NewRequest(new(http.Client))
|
||||
req.Headers = map[string]string{
|
||||
"Content-Type": "application/json",
|
||||
"Accept-Encoding": "",
|
||||
"cookie": cfg.Cookie,
|
||||
"x-csrftoken": cfg.CSRFtoken,
|
||||
"Referer": "https://leetcode.com/accounts/login/",
|
||||
"origin": "https://leetcode.com",
|
||||
}
|
||||
return req
|
||||
}
|
||||
|
||||
func getRaw(URL string) []byte {
|
||||
req := newReq()
|
||||
resp, err := req.Get(URL)
|
||||
if err != nil {
|
||||
fmt.Printf("getRaw: Get Error: " + err.Error())
|
||||
return []byte{}
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
fmt.Printf("getRaw: Read Error: " + err.Error())
|
||||
return []byte{}
|
||||
}
|
||||
if resp.StatusCode == 200 {
|
||||
fmt.Println("Get problem Success!")
|
||||
}
|
||||
return body
|
||||
}
|
||||
|
||||
func getProblemAllList() []byte {
|
||||
return getRaw(AllProblemURL)
|
||||
}
|
||||
|
||||
// Variables define
|
||||
type Variables struct {
|
||||
slug string
|
||||
}
|
||||
|
||||
func getQraphql(payload string) []byte {
|
||||
req := newReq()
|
||||
resp, err := req.PostForm(QraphqlURL, bytes.NewBuffer([]byte(payload)))
|
||||
if err != nil {
|
||||
fmt.Printf("getRaw: Get Error: " + err.Error())
|
||||
return []byte{}
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
fmt.Printf("getRaw: Read Error: " + err.Error())
|
||||
return []byte{}
|
||||
}
|
||||
if resp.StatusCode == 200 {
|
||||
fmt.Println("Get problem Success!")
|
||||
}
|
||||
return body
|
||||
}
|
||||
|
||||
func getTopicTag(variable string) string {
|
||||
return fmt.Sprintf(`{
|
||||
"operationName": "getTopicTag",
|
||||
"variables": {
|
||||
"slug": "%s"
|
||||
},
|
||||
"query": "query getTopicTag($slug: String!) { topicTag(slug: $slug) { name translatedName slug questions { status questionId questionFrontendId title titleSlug translatedTitle stats difficulty isPaidOnly topicTags { name translatedName slug __typename } companyTags { name translatedName slug __typename } __typename } frequencies __typename } favoritesLists { publicFavorites { ...favoriteFields __typename } privateFavorites { ...favoriteFields __typename } __typename }}fragment favoriteFields on FavoriteNode { idHash id name isPublicFavorite viewCount creator isWatched questions { questionId title titleSlug __typename } __typename}"
|
||||
}`, variable)
|
||||
}
|
||||
|
||||
func getTagProblemList(tag string) []byte {
|
||||
return getQraphql(getTopicTag(tag))
|
||||
}
|
39
ctl/statistic.go
Normal file
39
ctl/statistic.go
Normal file
@ -0,0 +1,39 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"sort"
|
||||
)
|
||||
|
||||
func statisticalData(problemsMap map[int]StatStatusPairs, solutionIds []int) (easyTotal, mediumTotal, hardTotal, optimizingEasy, optimizingMedium, optimizingHard int32, optimizingIds []int) {
|
||||
easyTotal, mediumTotal, hardTotal, optimizingEasy, optimizingMedium, optimizingHard, optimizingIds = 0, 0, 0, 0, 0, 0, []int{}
|
||||
for _, v := range problemsMap {
|
||||
switch DifficultyMap[v.Difficulty.Level] {
|
||||
case "Easy":
|
||||
{
|
||||
easyTotal++
|
||||
if v.Status == "ac" && BinarySearch(solutionIds, int(v.Stat.FrontendQuestionID)) == -1 {
|
||||
optimizingEasy++
|
||||
optimizingIds = append(optimizingIds, int(v.Stat.FrontendQuestionID))
|
||||
}
|
||||
}
|
||||
case "Medium":
|
||||
{
|
||||
mediumTotal++
|
||||
if v.Status == "ac" && BinarySearch(solutionIds, int(v.Stat.FrontendQuestionID)) == -1 {
|
||||
optimizingMedium++
|
||||
optimizingIds = append(optimizingIds, int(v.Stat.FrontendQuestionID))
|
||||
}
|
||||
}
|
||||
case "Hard":
|
||||
{
|
||||
hardTotal++
|
||||
if v.Status == "ac" && BinarySearch(solutionIds, int(v.Stat.FrontendQuestionID)) == -1 {
|
||||
optimizingHard++
|
||||
optimizingIds = append(optimizingIds, int(v.Stat.FrontendQuestionID))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
sort.Ints(optimizingIds)
|
||||
return easyTotal, mediumTotal, hardTotal, optimizingEasy, optimizingMedium, optimizingHard, optimizingIds
|
||||
}
|
282
ctl/tagproblem.go
Normal file
282
ctl/tagproblem.go
Normal file
@ -0,0 +1,282 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Graphql define
|
||||
type Graphql struct {
|
||||
OperationName string `json:"operationName"`
|
||||
Variables struct {
|
||||
TitleSlug string `json:"titleSlug"`
|
||||
} `json:"variables"`
|
||||
Query string `json:"query"`
|
||||
}
|
||||
|
||||
// GraphQLResp define
|
||||
type GraphQLResp struct {
|
||||
Data struct {
|
||||
TopicTag TopicTag `json:"topicTag"`
|
||||
FavoritesLists FavoritesLists `json:"favoritesLists"`
|
||||
} `json:"data"`
|
||||
}
|
||||
|
||||
// TopicTag define
|
||||
type TopicTag struct {
|
||||
Name string `json:"name"`
|
||||
TranslatedName string `json:"translatedName"`
|
||||
Slug string `json:"slug"`
|
||||
Questions []Question `json:"questions"`
|
||||
Frequencies string `json:"frequencies"`
|
||||
Typename string `json:"__typename"`
|
||||
}
|
||||
|
||||
// Question define
|
||||
type Question struct {
|
||||
Status string `json:"status"`
|
||||
QuestionID string `json:"questionId"`
|
||||
QuestionFrontendID string `json:"questionFrontendId"`
|
||||
Title string `json:"title"`
|
||||
TitleSlug string `json:"titleSlug"`
|
||||
TranslatedTitle string `json:"translatedTitle"`
|
||||
Stats string `json:"stats"`
|
||||
Difficulty string `json:"difficulty"`
|
||||
TopicTags []TopicTags `json:"topicTags"`
|
||||
CompanyTags interface{} `json:"companyTags"`
|
||||
Typename string `json:"__typename"`
|
||||
}
|
||||
|
||||
// TopicTags define
|
||||
type TopicTags struct {
|
||||
Name string `json:"name"`
|
||||
TranslatedName string `json:"translatedName"`
|
||||
Slug string `json:"slug"`
|
||||
Typename string `json:"__typename"`
|
||||
}
|
||||
|
||||
func (q Question) generateTagStatus() (TagStatus, error) {
|
||||
var ts TagStatus
|
||||
err := json.Unmarshal([]byte(q.Stats), &ts)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return ts, err
|
||||
}
|
||||
return ts, nil
|
||||
}
|
||||
|
||||
// TagStatus define
|
||||
type TagStatus struct {
|
||||
TotalAccepted string `json:"totalAccepted"`
|
||||
TotalSubmission string `json:"totalSubmission"`
|
||||
TotalAcceptedRaw int32 `json:"totalAcceptedRaw"`
|
||||
TotalSubmissionRaw int32 `json:"totalSubmissionRaw"`
|
||||
AcRate string `json:"acRate"`
|
||||
}
|
||||
|
||||
// ConvertMdModelFromQuestions define
|
||||
func ConvertMdModelFromQuestions(questions []Question) []Mdrow {
|
||||
mdrows := []Mdrow{}
|
||||
for _, question := range questions {
|
||||
res := Mdrow{}
|
||||
v, _ := strconv.Atoi(question.QuestionFrontendID)
|
||||
res.FrontendQuestionID = int32(v)
|
||||
res.QuestionTitle = strings.TrimSpace(question.Title)
|
||||
res.QuestionTitleSlug = strings.TrimSpace(question.TitleSlug)
|
||||
q, err := question.generateTagStatus()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
res.Acceptance = q.AcRate
|
||||
res.Difficulty = question.Difficulty
|
||||
mdrows = append(mdrows, res)
|
||||
}
|
||||
return mdrows
|
||||
}
|
||||
|
||||
// TagList define
|
||||
type TagList struct {
|
||||
FrontendQuestionID int32 `json:"question_id"`
|
||||
QuestionTitle string `json:"question__title"`
|
||||
SolutionPath string `json:"solution_path"`
|
||||
Acceptance string `json:"acceptance"`
|
||||
Difficulty string `json:"difficulty"`
|
||||
TimeComplexity string `json:"time_complexity"`
|
||||
SpaceComplexity string `json:"space_complexity"`
|
||||
Favorite string `json:"favorite"`
|
||||
}
|
||||
|
||||
// | 0001 | Two Sum | [Go]({{< relref "/ChapterFour/0001.Two-Sum.md" >}})| Easy | O(n)| O(n)|❤️|50%|
|
||||
func (t TagList) tableLine() string {
|
||||
return fmt.Sprintf("|%04d|%v|%v|%v|%v|%v|%v|%v|\n", t.FrontendQuestionID, t.QuestionTitle, t.SolutionPath, t.Difficulty, t.TimeComplexity, t.SpaceComplexity, t.Favorite, t.Acceptance)
|
||||
}
|
||||
|
||||
func standardizedTitle(orig string, frontendQuestionID int32) string {
|
||||
s0 := strings.TrimSpace(orig)
|
||||
s1 := strings.Replace(s0, " ", "-", -1)
|
||||
s2 := strings.Replace(s1, "'", "", -1)
|
||||
s3 := strings.Replace(s2, "%", "", -1)
|
||||
s4 := strings.Replace(s3, "(", "", -1)
|
||||
s5 := strings.Replace(s4, ")", "", -1)
|
||||
s6 := strings.Replace(s5, ",", "", -1)
|
||||
s7 := strings.Replace(s6, "?", "", -1)
|
||||
count := 0
|
||||
// 去掉 --- 这种情况,这种情况是由于题目标题中包含 - ,左右有空格,左右一填充,造成了 ---,3 个 -
|
||||
for i := 0; i < len(s7)-2; i++ {
|
||||
if s7[i] == '-' && s7[i+1] == '-' && s7[i+2] == '-' {
|
||||
fmt.Printf("【需要修正 --- 的标题是 %v】\n", fmt.Sprintf("%04d.%v", int(frontendQuestionID), s7))
|
||||
s7 = s7[:i+1] + s7[i+3:]
|
||||
count++
|
||||
}
|
||||
}
|
||||
if count > 0 {
|
||||
fmt.Printf("总共修正了 %v 个标题\n", count)
|
||||
}
|
||||
// 去掉 -- 这种情况,这种情况是由于题目标题中包含负号 -
|
||||
for i := 0; i < len(s7)-2; i++ {
|
||||
if s7[i] == '-' && s7[i+1] == '-' {
|
||||
fmt.Printf("【需要修正 -- 的标题是 %v】\n", fmt.Sprintf("%04d.%v", int(frontendQuestionID), s7))
|
||||
s7 = s7[:i+1] + s7[i+2:]
|
||||
count++
|
||||
}
|
||||
}
|
||||
if count > 0 {
|
||||
fmt.Printf("总共修正了 %v 个标题\n", count)
|
||||
}
|
||||
return s7
|
||||
}
|
||||
|
||||
// GenerateTagMdRows define
|
||||
func GenerateTagMdRows(solutionIds []int, metaMap map[int]TagList, mdrows []Mdrow, internal bool) []TagList {
|
||||
tl := []TagList{}
|
||||
for _, row := range mdrows {
|
||||
if BinarySearch(solutionIds, int(row.FrontendQuestionID)) != -1 {
|
||||
tmp := TagList{}
|
||||
tmp.FrontendQuestionID = row.FrontendQuestionID
|
||||
tmp.QuestionTitle = strings.TrimSpace(row.QuestionTitle)
|
||||
s7 := standardizedTitle(row.QuestionTitle, row.FrontendQuestionID)
|
||||
if internal {
|
||||
tmp.SolutionPath = fmt.Sprintf("[Go]({{< relref \"/ChapterFour/%v/%v.md\" >}})", GetChpaterFourFileNum(int(row.FrontendQuestionID)), fmt.Sprintf("%04d.%v", int(row.FrontendQuestionID), s7))
|
||||
} else {
|
||||
tmp.SolutionPath = fmt.Sprintf("[Go](https://books.halfrost.com/leetcode/ChapterFour/%v/%v)", GetChpaterFourFileNum(int(row.FrontendQuestionID)), fmt.Sprintf("%04d.%v", int(row.FrontendQuestionID), s7))
|
||||
}
|
||||
tmp.Acceptance = row.Acceptance
|
||||
tmp.Difficulty = row.Difficulty
|
||||
tmp.TimeComplexity = metaMap[int(row.FrontendQuestionID)].TimeComplexity
|
||||
tmp.SpaceComplexity = metaMap[int(row.FrontendQuestionID)].SpaceComplexity
|
||||
tmp.Favorite = metaMap[int(row.FrontendQuestionID)].Favorite
|
||||
tl = append(tl, tmp)
|
||||
}
|
||||
}
|
||||
return tl
|
||||
}
|
||||
|
||||
// TagLists define
|
||||
type TagLists struct {
|
||||
TagLists []TagList
|
||||
}
|
||||
|
||||
// | No. | Title | Solution | Difficulty | TimeComplexity | SpaceComplexity |Favorite| Acceptance |
|
||||
// |:--------:|:------- | :--------: | :----------: | :----: | :-----: | :-----: |:-----: |
|
||||
func (tls TagLists) table() string {
|
||||
res := "| No. | Title | Solution | Difficulty | TimeComplexity | SpaceComplexity |Favorite| Acceptance |\n"
|
||||
res += "|:--------:|:------- | :--------: | :----------: | :----: | :-----: | :-----: |:-----: |\n"
|
||||
for _, p := range tls.TagLists {
|
||||
res += p.tableLine()
|
||||
}
|
||||
// 加这一行是为了撑开整个表格
|
||||
res += "|------------|-------------------------------------------------------|-------| ----------------| ---------------|-------------|-------------|-------------|"
|
||||
return res
|
||||
}
|
||||
|
||||
// AvailableTagTable define
|
||||
func (tls TagLists) AvailableTagTable() string {
|
||||
return tls.table()
|
||||
}
|
||||
|
||||
// FavoritesLists define
|
||||
type FavoritesLists struct {
|
||||
PublicFavorites []int `json:"publicFavorites"`
|
||||
PrivateFavorites []struct {
|
||||
IDHash string `json:"idHash"`
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
IsPublicFavorite bool `json:"isPublicFavorite"`
|
||||
ViewCount int `json:"viewCount"`
|
||||
Creator string `json:"creator"`
|
||||
IsWatched bool `json:"isWatched"`
|
||||
Questions []struct {
|
||||
QuestionID string `json:"questionId"`
|
||||
Title string `json:"title"`
|
||||
TitleSlug string `json:"titleSlug"`
|
||||
Typename string `json:"__typename"`
|
||||
} `json:"questions"`
|
||||
Typename string `json:"__typename"`
|
||||
} `json:"privateFavorites"`
|
||||
Typename string `json:"__typename"`
|
||||
}
|
||||
|
||||
// Gproblem define
|
||||
type Gproblem struct {
|
||||
QuestionID string `json:"questionId"`
|
||||
QuestionFrontendID string `json:"questionFrontendId"`
|
||||
BoundTopicID int `json:"boundTopicId"`
|
||||
Title string `json:"title"`
|
||||
TitleSlug string `json:"titleSlug"`
|
||||
Content string `json:"content"`
|
||||
TranslatedTitle string `json:"translatedTitle"`
|
||||
TranslatedContent string `json:"translatedContent"`
|
||||
IsPaidOnly bool `json:"isPaidOnly"`
|
||||
Difficulty string `json:"difficulty"`
|
||||
Likes int `json:"likes"`
|
||||
Dislikes int `json:"dislikes"`
|
||||
IsLiked interface{} `json:"isLiked"`
|
||||
SimilarQuestions string `json:"similarQuestions"`
|
||||
Contributors []interface{} `json:"contributors"`
|
||||
LangToValidPlayground string `json:"langToValidPlayground"`
|
||||
TopicTags []struct {
|
||||
Name string `json:"name"`
|
||||
Slug string `json:"slug"`
|
||||
TranslatedName string `json:"translatedName"`
|
||||
Typename string `json:"__typename"`
|
||||
} `json:"topicTags"`
|
||||
CompanyTagStats interface{} `json:"companyTagStats"`
|
||||
CodeSnippets []GcodeSnippet `json:"codeSnippets"`
|
||||
Stats string `json:"stats"`
|
||||
Hints []interface{} `json:"hints"`
|
||||
Solution interface{} `json:"solution"`
|
||||
Status interface{} `json:"status"`
|
||||
SampleTestCase string `json:"sampleTestCase"`
|
||||
MetaData string `json:"metaData"`
|
||||
JudgerAvailable bool `json:"judgerAvailable"`
|
||||
JudgeType string `json:"judgeType"`
|
||||
MysqlSchemas []interface{} `json:"mysqlSchemas"`
|
||||
EnableRunCode bool `json:"enableRunCode"`
|
||||
EnableTestMode bool `json:"enableTestMode"`
|
||||
EnvInfo string `json:"envInfo"`
|
||||
Typename string `json:"__typename"`
|
||||
}
|
||||
|
||||
// Gstat define
|
||||
type Gstat struct {
|
||||
TotalAcs int `json:"total_acs"`
|
||||
QuestionTitle string `json:"question__title"`
|
||||
IsNewQuestion bool `json:"is_new_question"`
|
||||
QuestionArticleSlug string `json:"question__article__slug"`
|
||||
TotalSubmitted int `json:"total_submitted"`
|
||||
FrontendQuestionID int `json:"frontend_question_id"`
|
||||
QuestionTitleSlug string `json:"question__title_slug"`
|
||||
QuestionArticleLive bool `json:"question__article__live"`
|
||||
QuestionHide bool `json:"question__hide"`
|
||||
QuestionID int `json:"question_id"`
|
||||
}
|
||||
|
||||
// GcodeSnippet define
|
||||
type GcodeSnippet struct {
|
||||
Lang string `json:"lang"`
|
||||
LangSlug string `json:"langSlug"`
|
||||
Code string `json:"code"`
|
||||
Typename string `json:"__typename"`
|
||||
}
|
9
ctl/template/Array.md
Normal file
9
ctl/template/Array.md
Normal file
@ -0,0 +1,9 @@
|
||||
---
|
||||
title: 2.01 Array
|
||||
type: docs
|
||||
weight: 1
|
||||
---
|
||||
|
||||
# Array
|
||||
|
||||
{{.AvailableTagTable}}
|
101
ctl/template/Backtracking.md
Normal file
101
ctl/template/Backtracking.md
Normal file
@ -0,0 +1,101 @@
|
||||
---
|
||||
title: 2.08 ✅ Backtracking
|
||||
type: docs
|
||||
weight: 8
|
||||
---
|
||||
|
||||
# Backtracking
|
||||
|
||||

|
||||
|
||||
- 排列问题 Permutations。第 46 题,第 47 题。第 60 题,第 526 题,第 996 题。
|
||||
- 组合问题 Combination。第 39 题,第 40 题,第 77 题,第 216 题。
|
||||
- 排列和组合杂交问题。第 1079 题。
|
||||
- N 皇后终极解法(二进制解法)。第 51 题,第 52 题。
|
||||
- 数独问题。第 37 题。
|
||||
- 四个方向搜索。第 79 题,第 212 题,第 980 题。
|
||||
- 子集合问题。第 78 题,第 90 题。
|
||||
- Trie。第 208 题,第 211 题。
|
||||
- BFS 优化。第 126 题,第 127 题。
|
||||
- DFS 模板。(只是一个例子,不对应任何题)
|
||||
|
||||
```go
|
||||
func combinationSum2(candidates []int, target int) [][]int {
|
||||
if len(candidates) == 0 {
|
||||
return [][]int{}
|
||||
}
|
||||
c, res := []int{}, [][]int{}
|
||||
sort.Ints(candidates)
|
||||
findcombinationSum2(candidates, target, 0, c, &res)
|
||||
return res
|
||||
}
|
||||
|
||||
func findcombinationSum2(nums []int, target, index int, c []int, res *[][]int) {
|
||||
if target == 0 {
|
||||
b := make([]int, len(c))
|
||||
copy(b, c)
|
||||
*res = append(*res, b)
|
||||
return
|
||||
}
|
||||
for i := index; i < len(nums); i++ {
|
||||
if i > index && nums[i] == nums[i-1] { // 这里是去重的关键逻辑
|
||||
continue
|
||||
}
|
||||
if target >= nums[i] {
|
||||
c = append(c, nums[i])
|
||||
findcombinationSum2(nums, target-nums[i], i+1, c, res)
|
||||
c = c[:len(c)-1]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
- BFS 模板。(只是一个例子,不对应任何题)
|
||||
|
||||
```go
|
||||
func updateMatrix_BFS(matrix [][]int) [][]int {
|
||||
res := make([][]int, len(matrix))
|
||||
if len(matrix) == 0 || len(matrix[0]) == 0 {
|
||||
return res
|
||||
}
|
||||
queue := make([][]int, 0)
|
||||
for i, _ := range matrix {
|
||||
res[i] = make([]int, len(matrix[0]))
|
||||
for j, _ := range res[i] {
|
||||
if matrix[i][j] == 0 {
|
||||
res[i][j] = -1
|
||||
queue = append(queue, []int{i, j})
|
||||
}
|
||||
}
|
||||
}
|
||||
level := 1
|
||||
for len(queue) > 0 {
|
||||
size := len(queue)
|
||||
for size > 0 {
|
||||
size -= 1
|
||||
node := queue[0]
|
||||
queue = queue[1:]
|
||||
i, j := node[0], node[1]
|
||||
for _, direction := range [][]int{{-1, 0}, {1, 0}, {0, 1}, {0, -1}} {
|
||||
x := i + direction[0]
|
||||
y := j + direction[1]
|
||||
if x < 0 || x >= len(matrix) || y < 0 || y >= len(matrix[0]) || res[x][y] < 0 || res[x][y] > 0 {
|
||||
continue
|
||||
}
|
||||
res[x][y] = level
|
||||
queue = append(queue, []int{x, y})
|
||||
}
|
||||
}
|
||||
level++
|
||||
}
|
||||
for i, row := range res {
|
||||
for j, cell := range row {
|
||||
if cell == -1 {
|
||||
res[i][j] = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
return res
|
||||
}
|
||||
```
|
||||
|
||||
{{.AvailableTagTable}}
|
11
ctl/template/Binary_Indexed_Tree.md
Normal file
11
ctl/template/Binary_Indexed_Tree.md
Normal file
@ -0,0 +1,11 @@
|
||||
---
|
||||
title: 2.19 ✅ Binary Indexed Tree
|
||||
type: docs
|
||||
weight: 19
|
||||
---
|
||||
|
||||
# Binary Indexed Tree
|
||||
|
||||

|
||||
|
||||
{{.AvailableTagTable}}
|
132
ctl/template/Binary_Search.md
Normal file
132
ctl/template/Binary_Search.md
Normal file
@ -0,0 +1,132 @@
|
||||
---
|
||||
title: 2.11 Binary Search
|
||||
type: docs
|
||||
weight: 11
|
||||
---
|
||||
|
||||
# Binary Search
|
||||
|
||||
- 二分搜索的经典写法。需要注意的三点:
|
||||
1. 循环退出条件,注意是 low <= high,而不是 low < high。
|
||||
2. mid 的取值,mid := low + (high-low)>>1
|
||||
3. low 和 high 的更新。low = mid + 1,high = mid - 1。
|
||||
|
||||
```go
|
||||
func binarySearchMatrix(nums []int, target int) int {
|
||||
low, high := 0, len(nums)-1
|
||||
for low <= high {
|
||||
mid := low + (high-low)>>1
|
||||
if nums[mid] == target {
|
||||
return mid
|
||||
} else if nums[mid] > target {
|
||||
high = mid - 1
|
||||
} else {
|
||||
low = mid + 1
|
||||
}
|
||||
}
|
||||
return -1
|
||||
}
|
||||
```
|
||||
|
||||
- 二分搜索的变种写法。有 4 个基本变种:
|
||||
1. 查找第一个与 target 相等的元素,时间复杂度 O(logn)
|
||||
2. 查找最后一个与 target 相等的元素,时间复杂度 O(logn)
|
||||
3. 查找第一个大于等于 target 的元素,时间复杂度 O(logn)
|
||||
4. 查找最后一个小于等于 target 的元素,时间复杂度 O(logn)
|
||||
|
||||
```go
|
||||
// 二分查找第一个与 target 相等的元素,时间复杂度 O(logn)
|
||||
func searchFirstEqualElement(nums []int, target int) int {
|
||||
low, high := 0, len(nums)-1
|
||||
for low <= high {
|
||||
mid := low + ((high - low) >> 1)
|
||||
if nums[mid] > target {
|
||||
high = mid - 1
|
||||
} else if nums[mid] < target {
|
||||
low = mid + 1
|
||||
} else {
|
||||
if (mid == 0) || (nums[mid-1] != target) { // 找到第一个与 target 相等的元素
|
||||
return mid
|
||||
}
|
||||
high = mid - 1
|
||||
}
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
// 二分查找最后一个与 target 相等的元素,时间复杂度 O(logn)
|
||||
func searchLastEqualElement(nums []int, target int) int {
|
||||
low, high := 0, len(nums)-1
|
||||
for low <= high {
|
||||
mid := low + ((high - low) >> 1)
|
||||
if nums[mid] > target {
|
||||
high = mid - 1
|
||||
} else if nums[mid] < target {
|
||||
low = mid + 1
|
||||
} else {
|
||||
if (mid == len(nums)-1) || (nums[mid+1] != target) { // 找到最后一个与 target 相等的元素
|
||||
return mid
|
||||
}
|
||||
low = mid + 1
|
||||
}
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
// 二分查找第一个大于等于 target 的元素,时间复杂度 O(logn)
|
||||
func searchFirstGreaterElement(nums []int, target int) int {
|
||||
low, high := 0, len(nums)-1
|
||||
for low <= high {
|
||||
mid := low + ((high - low) >> 1)
|
||||
if nums[mid] >= target {
|
||||
if (mid == 0) || (nums[mid-1] < target) { // 找到第一个大于等于 target 的元素
|
||||
return mid
|
||||
}
|
||||
high = mid - 1
|
||||
} else {
|
||||
low = mid + 1
|
||||
}
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
// 二分查找最后一个小于等于 target 的元素,时间复杂度 O(logn)
|
||||
func searchLastLessElement(nums []int, target int) int {
|
||||
low, high := 0, len(nums)-1
|
||||
for low <= high {
|
||||
mid := low + ((high - low) >> 1)
|
||||
if nums[mid] <= target {
|
||||
if (mid == len(nums)-1) || (nums[mid+1] > target) { // 找到最后一个小于等于 target 的元素
|
||||
return mid
|
||||
}
|
||||
low = mid + 1
|
||||
} else {
|
||||
high = mid - 1
|
||||
}
|
||||
}
|
||||
return -1
|
||||
}
|
||||
```
|
||||
|
||||
- 在基本有序的数组中用二分搜索。经典解法可以解,变种写法也可以写,常见的题型,在山峰数组中找山峰,在旋转有序数组中找分界点。第 33 题,第 81 题,第 153 题,第 154 题,第 162 题,第 852 题
|
||||
|
||||
```go
|
||||
func peakIndexInMountainArray(A []int) int {
|
||||
low, high := 0, len(A)-1
|
||||
for low < high {
|
||||
mid := low + (high-low)>>1
|
||||
// 如果 mid 较大,则左侧存在峰值,high = m,如果 mid + 1 较大,则右侧存在峰值,low = mid + 1
|
||||
if A[mid] > A[mid+1] {
|
||||
high = mid
|
||||
} else {
|
||||
low = mid + 1
|
||||
}
|
||||
}
|
||||
return low
|
||||
}
|
||||
```
|
||||
|
||||
- max-min 最大值最小化问题。求在最小满足条件的情况下的最大值。第 410 题,第 875 题,第 1011 题,第 1283 题。
|
||||
|
||||
|
||||
{{.AvailableTagTable}}
|
45
ctl/template/Bit_Manipulation.md
Normal file
45
ctl/template/Bit_Manipulation.md
Normal file
@ -0,0 +1,45 @@
|
||||
---
|
||||
title: 2.15 ✅ Bit Manipulation
|
||||
type: docs
|
||||
weight: 15
|
||||
---
|
||||
|
||||
# Bit Manipulation
|
||||
|
||||

|
||||
|
||||
- 异或的特性。第 136 题,第 268 题,第 389 题,第 421 题,
|
||||
|
||||
```go
|
||||
x ^ 0 = x
|
||||
x ^ 11111……1111 = ~x
|
||||
x ^ (~x) = 11111……1111
|
||||
x ^ x = 0
|
||||
a ^ b = c => a ^ c = b => b ^ c = a (交换律)
|
||||
a ^ b ^ c = a ^ (b ^ c) = (a ^ b)^ c (结合律)
|
||||
```
|
||||
|
||||
- 构造特殊 Mask,将特殊位置放 0 或 1。
|
||||
|
||||
```go
|
||||
将 x 最右边的 n 位清零, x & ( ~0 << n )
|
||||
获取 x 的第 n 位值(0 或者 1),(x >> n) & 1
|
||||
获取 x 的第 n 位的幂值,x & (1 << (n - 1))
|
||||
仅将第 n 位置为 1,x | (1 << n)
|
||||
仅将第 n 位置为 0,x & (~(1 << n))
|
||||
将 x 最高位至第 n 位(含)清零,x & ((1 << n) - 1)
|
||||
将第 n 位至第 0 位(含)清零,x & (~((1 << (n + 1)) - 1))
|
||||
```
|
||||
|
||||
- 有特殊意义的 & 位操作运算。第 260 题,第 201 题,第 318 题,第 371 题,第 397 题,第 461 题,第 693 题,
|
||||
|
||||
```go
|
||||
X & 1 == 1 判断是否是奇数(偶数)
|
||||
X & = (X - 1) 将最低位(LSB)的 1 清零
|
||||
X & -X 得到最低位(LSB)的 1
|
||||
X & ~X = 0
|
||||
```
|
||||
|
||||
|
||||
|
||||
{{.AvailableTagTable}}
|
10
ctl/template/Breadth_First_Search.md
Normal file
10
ctl/template/Breadth_First_Search.md
Normal file
@ -0,0 +1,10 @@
|
||||
---
|
||||
title: 2.10 Breadth First Search
|
||||
type: docs
|
||||
weight: 10
|
||||
---
|
||||
|
||||
# Breadth First Search
|
||||
|
||||
|
||||
{{.AvailableTagTable}}
|
10
ctl/template/Depth_First_Search.md
Normal file
10
ctl/template/Depth_First_Search.md
Normal file
@ -0,0 +1,10 @@
|
||||
---
|
||||
title: 2.09 Depth First Search
|
||||
type: docs
|
||||
weight: 9
|
||||
---
|
||||
|
||||
# Depth First Search
|
||||
|
||||
|
||||
{{.AvailableTagTable}}
|
10
ctl/template/Dynamic_Programming.md
Normal file
10
ctl/template/Dynamic_Programming.md
Normal file
@ -0,0 +1,10 @@
|
||||
---
|
||||
title: 2.07 Dynamic Programming
|
||||
type: docs
|
||||
weight: 7
|
||||
---
|
||||
|
||||
# Dynamic Programming
|
||||
|
||||
|
||||
{{.AvailableTagTable}}
|
10
ctl/template/Hash_Table.md
Normal file
10
ctl/template/Hash_Table.md
Normal file
@ -0,0 +1,10 @@
|
||||
---
|
||||
title: 2.13 Hash Table
|
||||
type: docs
|
||||
weight: 13
|
||||
---
|
||||
|
||||
# Hash Table
|
||||
|
||||
|
||||
{{.AvailableTagTable}}
|
24
ctl/template/Linked_List.md
Normal file
24
ctl/template/Linked_List.md
Normal file
@ -0,0 +1,24 @@
|
||||
---
|
||||
title: 2.04 ✅ Linked List
|
||||
type: docs
|
||||
weight: 4
|
||||
---
|
||||
|
||||
# Linked List
|
||||
|
||||

|
||||
|
||||
|
||||
- 巧妙的构造虚拟头结点。可以使遍历处理逻辑更加统一。
|
||||
- 灵活使用递归。构造递归条件,使用递归可以巧妙的解题。不过需要注意有些题目不能使用递归,因为递归深度太深会导致超时和栈溢出。
|
||||
- 链表区间逆序。第 92 题。
|
||||
- 链表寻找中间节点。第 876 题。链表寻找倒数第 n 个节点。第 19 题。只需要一次遍历就可以得到答案。
|
||||
- 合并 K 个有序链表。第 21 题,第 23 题。
|
||||
- 链表归类。第 86 题,第 328 题。
|
||||
- 链表排序,时间复杂度要求 O(n * log n),空间复杂度 O(1)。只有一种做法,归并排序,至顶向下归并。第 148 题。
|
||||
- 判断链表是否存在环,如果有环,输出环的交叉点的下标;判断 2 个链表是否有交叉点,如果有交叉点,输出交叉点。第 141 题,第 142 题,第 160 题。
|
||||
|
||||
|
||||
|
||||
|
||||
{{.AvailableTagTable}}
|
10
ctl/template/Math.md
Normal file
10
ctl/template/Math.md
Normal file
@ -0,0 +1,10 @@
|
||||
---
|
||||
title: 2.12 Math
|
||||
type: docs
|
||||
weight: 12
|
||||
---
|
||||
|
||||
# Math
|
||||
|
||||
|
||||
{{.AvailableTagTable}}
|
38
ctl/template/Segment_Tree.md
Normal file
38
ctl/template/Segment_Tree.md
Normal file
@ -0,0 +1,38 @@
|
||||
---
|
||||
title: 2.18 ✅ Segment Tree
|
||||
type: docs
|
||||
weight: 18
|
||||
---
|
||||
|
||||
# Segment Tree
|
||||
|
||||

|
||||
|
||||
- 线段树的经典数组实现写法。将合并两个节点 pushUp 逻辑抽象出来了,可以实现任意操作(常见的操作有:加法,取 max,min 等等)。第 218 题,第 303 题,第 307 题,第 699 题。
|
||||
- 计数线段树的经典写法。第 315 题,第 327 题,第 493 题。
|
||||
- 线段树的树的实现写法。第 715 题,第 732 题。
|
||||
- 区间懒惰更新。第 218 题,第 699 题。
|
||||
- 离散化。离散化需要注意一个特殊情况:假如三个区间为 [1,10] [1,4] [6,10],离散化后 x[1]=1,x[2]=4,x[3]=6,x[4]=10。第一个区间为 [1,4],第二个区间为 [1,2],第三个区间为 [3,4],这样一来,区间一 = 区间二 + 区间三,这和离散前的模型不符,离散前,很明显,区间一 > 区间二 + 区间三。正确的做法是:在相差大于 1 的数间加一个数,例如在上面 1 4 6 10 中间加 5,即可 x[1]=1,x[2]=4,x[3]=5,x[4]=6,x[5]=10。这样处理之后,区间一是 1-5 ,区间二是 1-2 ,区间三是 4-5 。
|
||||
- 灵活构建线段树。线段树节点可以存储多条信息,合并两个节点的 pushUp 操作也可以是多样的。第 850 题,第 1157 题。
|
||||
|
||||
|
||||
线段树[题型](https://blog.csdn.net/xuechelingxiao/article/details/38313105)从简单到困难:
|
||||
|
||||
1. 单点更新:
|
||||
[HDU 1166 敌兵布阵](http://acm.hdu.edu.cn/showproblem.php?pid=1166) update:单点增减 query:区间求和
|
||||
[HDU 1754 I Hate It](http://acm.hdu.edu.cn/showproblem.php?pid=1754) update:单点替换 query:区间最值
|
||||
[HDU 1394 Minimum Inversion Number](http://acm.hdu.edu.cn/showproblem.php?pid=1394) update:单点增减 query:区间求和
|
||||
[HDU 2795 Billboard](http://acm.hdu.edu.cn/showproblem.php?pid=2795) query:区间求最大值的位子(直接把update的操作在query里做了)
|
||||
2. 区间更新:
|
||||
[HDU 1698 Just a Hook](http://acm.hdu.edu.cn/showproblem.php?pid=1698) update:成段替换 (由于只query一次总区间,所以可以直接输出 1 结点的信息)
|
||||
[POJ 3468 A Simple Problem with Integers](http://poj.org/problem?id=3468) update:成段增减 query:区间求和
|
||||
[POJ 2528 Mayor’s posters](http://poj.org/problem?id=2528) 离散化 + update:成段替换 query:简单hash
|
||||
[POJ 3225 Help with Intervals](http://poj.org/problem?id=3225) update:成段替换,区间异或 query:简单hash
|
||||
3. 区间合并(这类题目会询问区间中满足条件的连续最长区间,所以PushUp的时候需要对左右儿子的区间进行合并):
|
||||
[POJ 3667 Hotel](http://poj.org/problem?id=3667) update:区间替换 query:询问满足条件的最左端点
|
||||
4. 扫描线(这类题目需要将一些操作排序,然后从左到右用一根扫描线扫过去最典型的就是矩形面积并,周长并等题):
|
||||
[HDU 1542 Atlantis](http://acm.hdu.edu.cn/showproblem.php?pid=1542) update:区间增减 query:直接取根节点的值
|
||||
[HDU 1828 Picture](http://acm.hdu.edu.cn/showproblem.php?pid=1828) update:区间增减 query:直接取根节点的值
|
||||
|
||||
|
||||
{{.AvailableTagTable}}
|
30
ctl/template/Sliding_Window.md
Normal file
30
ctl/template/Sliding_Window.md
Normal file
@ -0,0 +1,30 @@
|
||||
---
|
||||
title: 2.17 ✅ Sliding Window
|
||||
type: docs
|
||||
weight: 17
|
||||
---
|
||||
|
||||
# Sliding Window
|
||||
|
||||

|
||||
|
||||
- 双指针滑动窗口的经典写法。右指针不断往右移,移动到不能往右移动为止(具体条件根据题目而定)。当右指针到最右边以后,开始挪动左指针,释放窗口左边界。第 3 题,第 76 题,第 209 题,第 424 题,第 438 题,第 567 题,第 713 题,第 763 题,第 845 题,第 881 题,第 904 题,第 978 题,第 992 题,第 1004 题,第 1040 题,第 1052 题。
|
||||
|
||||
```c
|
||||
left, right := 0, -1
|
||||
|
||||
for left < len(s) {
|
||||
if right+1 < len(s) && freq[s[right+1]-'a'] == 0 {
|
||||
freq[s[right+1]-'a']++
|
||||
right++
|
||||
} else {
|
||||
freq[s[left]-'a']--
|
||||
left++
|
||||
}
|
||||
result = max(result, right-left+1)
|
||||
}
|
||||
```
|
||||
- 滑动窗口经典题。第 239 题,第 480 题。
|
||||
|
||||
|
||||
{{.AvailableTagTable}}
|
19
ctl/template/Sorting.md
Normal file
19
ctl/template/Sorting.md
Normal file
@ -0,0 +1,19 @@
|
||||
---
|
||||
title: 2.14 ✅ Sorting
|
||||
type: docs
|
||||
weight: 14
|
||||
---
|
||||
|
||||
# Sorting
|
||||
|
||||

|
||||
|
||||
- 深刻的理解多路快排。第 75 题。
|
||||
- 链表的排序,插入排序(第 147 题)和归并排序(第 148 题)
|
||||
- 桶排序和基数排序。第 164 题。
|
||||
- "摆动排序"。第 324 题。
|
||||
- 两两不相邻的排序。第 767 题,第 1054 题。
|
||||
- "饼子排序"。第 969 题。
|
||||
|
||||
|
||||
{{.AvailableTagTable}}
|
18
ctl/template/Stack.md
Normal file
18
ctl/template/Stack.md
Normal file
@ -0,0 +1,18 @@
|
||||
---
|
||||
title: 2.05 ✅ Stack
|
||||
type: docs
|
||||
weight: 5
|
||||
---
|
||||
|
||||
# Stack
|
||||
|
||||

|
||||
|
||||
- 括号匹配问题及类似问题。第 20 题,第 921 题,第 1021 题。
|
||||
- 栈的基本 pop 和 push 操作。第 71 题,第 150 题,第 155 题,第 224 题,第 225 题,第 232 题,第 946 题,第 1047 题。
|
||||
- 利用栈进行编码问题。第 394 题,第 682 题,第 856 题,第 880 题。
|
||||
- **单调栈**。**利用栈维护一个单调递增或者递减的下标数组**。第 84 题,第 456 题,第 496 题,第 503 题,第 739 题,第 901 题,第 907 题,第 1019 题。
|
||||
|
||||
|
||||
|
||||
{{.AvailableTagTable}}
|
10
ctl/template/String.md
Normal file
10
ctl/template/String.md
Normal file
@ -0,0 +1,10 @@
|
||||
---
|
||||
title: 2.02 String
|
||||
type: docs
|
||||
weight: 2
|
||||
---
|
||||
|
||||
# String
|
||||
|
||||
|
||||
{{.AvailableTagTable}}
|
10
ctl/template/Tree.md
Normal file
10
ctl/template/Tree.md
Normal file
@ -0,0 +1,10 @@
|
||||
---
|
||||
title: 2.06 Tree
|
||||
type: docs
|
||||
weight: 6
|
||||
---
|
||||
|
||||
# Tree
|
||||
|
||||
|
||||
{{.AvailableTagTable}}
|
33
ctl/template/Two_Pointers.md
Normal file
33
ctl/template/Two_Pointers.md
Normal file
@ -0,0 +1,33 @@
|
||||
---
|
||||
title: 2.03 ✅ Two Pointers
|
||||
type: docs
|
||||
weight: 3
|
||||
---
|
||||
|
||||
# Two Pointers
|
||||
|
||||

|
||||
|
||||
- 双指针滑动窗口的经典写法。右指针不断往右移,移动到不能往右移动为止(具体条件根据题目而定)。当右指针到最右边以后,开始挪动左指针,释放窗口左边界。第 3 题,第 76 题,第 209 题,第 424 题,第 438 题,第 567 题,第 713 题,第 763 题,第 845 题,第 881 题,第 904 题,第 978 题,第 992 题,第 1004 题,第 1040 题,第 1052 题。
|
||||
|
||||
```c
|
||||
left, right := 0, -1
|
||||
|
||||
for left < len(s) {
|
||||
if right+1 < len(s) && freq[s[right+1]-'a'] == 0 {
|
||||
freq[s[right+1]-'a']++
|
||||
right++
|
||||
} else {
|
||||
freq[s[left]-'a']--
|
||||
left++
|
||||
}
|
||||
result = max(result, right-left+1)
|
||||
}
|
||||
```
|
||||
|
||||
- 快慢指针可以查找重复数字,时间复杂度 O(n),第 287 题。
|
||||
- 替换字母以后,相同字母能出现连续最长的长度。第 424 题。
|
||||
- SUM 问题集。第 1 题,第 15 题,第 16 题,第 18 题,第 167 题,第 923 题,第 1074 题。
|
||||
|
||||
|
||||
{{.AvailableTagTable}}
|
20
ctl/template/Union_Find.md
Normal file
20
ctl/template/Union_Find.md
Normal file
@ -0,0 +1,20 @@
|
||||
---
|
||||
title: 2.16 ✅ Union Find
|
||||
type: docs
|
||||
weight: 16
|
||||
---
|
||||
|
||||
# Union Find
|
||||
|
||||

|
||||
|
||||
- 灵活使用并查集的思想,熟练掌握并查集的[模板]({{< relref "/ChapterThree/UnionFind.md" >}}),模板中有两种并查集的实现方式,一种是路径压缩 + 秩优化的版本,另外一种是计算每个集合中元素的个数 + 最大集合元素个数的版本,这两种版本都有各自使用的地方。能使用第一类并查集模板的题目有:第 128 题,第 130 题,第 547 题,第 684 题,第 721 题,第 765 题,第 778 题,第 839 题,第 924 题,第 928 题,第 947 题,第 952 题,第 959 题,第 990 题。能使用第二类并查集模板的题目有:第 803 题,第 952 题。第 803 题秩优化和统计集合个数这些地方会卡时间,如果不优化,会 TLE。
|
||||
- 并查集是一种思想,有些题需要灵活使用这种思想,而不是死套模板,如第 399 题,这一题是 stringUnionFind,利用并查集思想实现的。这里每个节点是基于字符串和 map 的,而不是单纯的用 int 节点编号实现的。
|
||||
- 有些题死套模板反而做不出来,比如第 685 题,这一题不能路径压缩和秩优化,因为题目中涉及到有向图,需要知道节点的前驱节点,如果路径压缩了,这一题就没法做了。这一题不需要路径压缩和秩优化。
|
||||
- 灵活的抽象题目给的信息,将给定的信息合理的编号,使用并查集解题,并用 map 降低时间复杂度,如第 721 题,第 959 题。
|
||||
- 关于地图,砖块,网格的题目,可以新建一个特殊节点,将四周边缘的砖块或者网格都 union() 到这个特殊节点上。第 130 题,第 803 题。
|
||||
- 能用并查集的题目,一般也可以用 DFS 和 BFS 解答,只不过时间复杂度会高一点。
|
||||
|
||||
|
||||
|
||||
{{.AvailableTagTable}}
|
4
ctl/template/collapseSection.md
Normal file
4
ctl/template/collapseSection.md
Normal file
@ -0,0 +1,4 @@
|
||||
---
|
||||
bookCollapseSection: true
|
||||
weight: 20
|
||||
---
|
9
ctl/template/menu.md
Normal file
9
ctl/template/menu.md
Normal file
@ -0,0 +1,9 @@
|
||||
---
|
||||
headless: true
|
||||
---
|
||||
|
||||
<hr>
|
||||
|
||||
{{.BookMenu}}
|
||||
|
||||
<br />
|
645
ctl/template/template.markdown
Normal file
645
ctl/template/template.markdown
Normal file
@ -0,0 +1,645 @@
|
||||
|
||||
# LeetCode in Go
|
||||
[LeetCode Online Judge](https://leetcode.com/) is a website containing many **algorithm questions**. Most of them are real interview questions of **Google, Facebook, LinkedIn, Apple**, etc. and it always help to sharp our algorithm Skills. Level up your coding skills and quickly land a job. This is the best place to expand your knowledge and get prepared for your next interview. This repo shows my solutions in Go with the code style strictly follows the [Google Golang Style Guide](https://github.com/golang/go/wiki/CodeReviewComments). Please feel free to reference and **STAR** to support this repo, thank you!
|
||||
|
||||
|
||||
<p align='center'>
|
||||
<img src='./logo.png'>
|
||||
</p>
|
||||
|
||||

|
||||
|
||||
<p align='center'>
|
||||
<a href="https://github.com/halfrost/leetcode-go/releases/" rel="nofollow"><img alt="GitHub All Releases" src="https://img.shields.io/github/downloads/halfrost/LeetCode-Go/total?label=PDF%20downloads"></a>
|
||||
<img src="https://img.shields.io/badge/Total%20Word%20Count-738884-success">
|
||||
<a href="https://github.com/halfrost/leetcode-go/actions" rel="nofollow"><img src="https://github.com/halfrost/leetcode-go/workflows/Deploy%20leetcode-cookbook/badge.svg?branch=master"></a>
|
||||
<a href="https://travis-ci.org/github/halfrost/LeetCode-Go" rel="nofollow"><img src="https://travis-ci.org/halfrost/LeetCode-Go.svg?branch=master"></a>
|
||||
<a href="https://goreportcard.com/report/github.com/halfrost/LeetCode-Go" rel="nofollow"><img src="https://goreportcard.com/badge/github.com/halfrost/LeetCode-Go"></a>
|
||||
<img src="https://img.shields.io/badge/runtime%20beats-100%25-success">
|
||||
<a href="https://codecov.io/gh/halfrost/LeetCode-Go"><img src="https://codecov.io/gh/halfrost/LeetCode-Go/branch/master/graph/badge.svg" /></a>
|
||||
<!--<img alt="GitHub go.mod Go version" src="https://img.shields.io/github/go-mod/go-version/halfrost/LeetCode-Go?color=26C2F0">-->
|
||||
<img alt="Support Go version" src="https://img.shields.io/badge/Go-v1.15-26C2F0">
|
||||
<img src="https://visitor-badge.laobi.icu/badge?page_id=halfrost.LeetCode-Go">
|
||||
</p>
|
||||
|
||||
<p align='center'>
|
||||
<a href="https://github.com/halfrost/leetcode-go/blob/master/LICENSE"><img alt="GitHub" src="https://img.shields.io/github/license/halfrost/LeetCode-Go?label=License"></a>
|
||||
<img src="https://img.shields.io/badge/License-CC-000000.svg">
|
||||
<a href="https://leetcode.com/halfrost/"><img src="https://img.shields.io/badge/@halfrost-8751-yellow.svg">
|
||||
<img src="https://img.shields.io/badge/language-Golang-26C2F0.svg">
|
||||
<a href="https://halfrost.com"><img src="https://img.shields.io/badge/Blog-Halfrost--Field-80d4f9.svg?style=flat"></a>
|
||||
<a href="http://weibo.com/halfrost"><img src="https://img.shields.io/badge/weibo-@halfrost-f974ce.svg?style=flat&colorA=f4292e"></a>
|
||||
<a href="https://twitter.com/halffrost"><img src="https://img.shields.io/badge/twitter-@halffrost-F8E81C.svg?style=flat&colorA=009df2"></a>
|
||||
<a href="https://www.zhihu.com/people/halfrost/activities"><img src="https://img.shields.io/badge/%E7%9F%A5%E4%B9%8E-@halfrost-fd6f32.svg?style=flat&colorA=0083ea"></a>
|
||||
<img src="https://img.shields.io/badge/made%20with-=1-blue.svg">
|
||||
<a href="https://github.com/halfrost/leetcode-go/pulls"><img src="https://img.shields.io/badge/PR-Welcome-brightgreen.svg"></a>
|
||||
</p>
|
||||
|
||||
支持 Progressive Web Apps 和 Dark Mode 的题解电子书《LeetCode Cookbook》 <a href="https://books.halfrost.com/leetcode/" rel="nofollow">Online Reading</a>
|
||||
|
||||
<p align='center'>
|
||||
<a href="https://books.halfrost.com/leetcode/"><img src="https://img.halfrost.com/Leetcode/Cookbook_Safari_0.png"></a>
|
||||
<a href="https://books.halfrost.com/leetcode/"><img src="https://img.halfrost.com/Leetcode/Cookbook_Chrome_PWA.png"></a>
|
||||
</p>
|
||||
|
||||
离线版本的电子书《LeetCode Cookbook》PDF <a href="https://github.com/halfrost/leetcode-go/releases/" rel="nofollow">Download here</a>
|
||||
|
||||
<p align='center'>
|
||||
<a href="https://github.com/halfrost/leetcode-go/releases/"><img src="https://img.halfrost.com/Leetcode/Cookbook.png"></a>
|
||||
</p>
|
||||
|
||||
通过 iOS / Android 浏览器安装 PWA 版《LeetCode Cookbook》至设备桌面随时学习
|
||||
|
||||
<p align='center'>
|
||||
<a href="https://books.halfrost.com/leetcode/"><img src="https://img.halfrost.com/Leetcode/Cookbook_PWA_iPad.png"></a>
|
||||
<a href="https://books.halfrost.com/leetcode/"><img src="https://img.halfrost.com/Leetcode/Cookbook_PWA_iPad_example1__.png"></a>
|
||||
<a href="https://books.halfrost.com/leetcode/"><img src="https://img.halfrost.com/Leetcode/Cookbook_PWA_iPad_example2__.png"></a>
|
||||
</p>
|
||||
|
||||
|
||||
## Data Structures
|
||||
|
||||
> 标识了 ✅ 的专题是完成所有题目了的,没有标识的是还没有做完所有题目的
|
||||
|
||||
<a href="https://books.halfrost.com/leetcode/"><img src="./website/static/logo.png" alt="logo" height="550" align="right" /></a>
|
||||
|
||||
* [Array](#array)
|
||||
* [String](#string)
|
||||
* [✅ Two Pointers](#two-pointers)
|
||||
* [✅ Linked List](#linked-list)
|
||||
* [✅ Stack](#stack)
|
||||
* [Tree](#tree)
|
||||
* [Dynamic programming](#dynamic-programming)
|
||||
* [✅ Backtracking](#backtracking)
|
||||
* [Depth First Search](#depth-first-search)
|
||||
* [Breadth First Search](#breadth-first-search)
|
||||
* [Binary Search](#binary-search)
|
||||
* [Math](#math)
|
||||
* [Hash Table](#hash-table)
|
||||
* [✅ Sort](#sort)
|
||||
* [✅ Bit Manipulation](#bit-manipulation)
|
||||
* [✅ Union Find](#union-find)
|
||||
* [✅ Sliding Window](#sliding-window)
|
||||
* [✅ Segment Tree](#segment-tree)
|
||||
* [✅ Binary Indexed Tree](#binary-indexed-tree)
|
||||
|
||||
<br>
|
||||
<br>
|
||||
|
||||
| 数据结构 | 变种 | 相关题目 | 讲解文章 |
|
||||
|:-------:|:-------|:------|:------|
|
||||
|顺序线性表:向量||||
|
||||
|单链表|1. 双向链表<br>2. 静态链表<br>3. 对称矩阵<br>4. 稀疏矩阵|||
|
||||
|哈希表|1. 散列函数<br>2. 解决碰撞/填充因子<br>|||
|
||||
|栈和队列|1. 广义栈<br>2. 双端队列<br>|||
|
||||
|队列|1. 链表实现<br>2. 循环数组实现<br>3. 双端队列|||
|
||||
|字符串|1. KMP算法<br>2. 有限状态自动机<br>3. 模式匹配有限状态自动机<br>4. BM 模式匹配算法<br>5. BM-KMP 算法<br>6. BF 算法|||
|
||||
|树|1. 二叉树<br>2. 并查集<br>3. Huffman 树|||
|
||||
|数组实现的堆|1. 极大堆和极小堆<br>2. 极大极小堆<br>3. 双端堆<br>4. d 叉堆|||
|
||||
|树实现的堆|1. 左堆<br>2. 扁堆<br>3. 二项式堆<br>4. 斐波那契堆<br>5. 配对堆|||
|
||||
|查找|1. 哈希表<br>2. 跳跃表<br>3. 排序二叉树<br>4. AVL 树<br>5. B 树 / B+ 树 / B* 树<br>6. AA 树<br>7. 红黑树<br>8. 排序二叉堆<br>9. Splay 树<br>10. 双链树<br>11. Trie 树<br>12. R 树|||
|
||||
|--------------------------------------------|--------------------------------------------------------------------------------------------|---------------------------|-----------------------------------|
|
||||
|
||||
|
||||
## Algorithm
|
||||
|
||||
|
||||
| 算法 | 具体类型 | 相关题目 | 讲解文章 |
|
||||
|:-------:|:-------|:------|:------|
|
||||
|排序算法|1. 冒泡排序<br>2. 插入排序<br>3. 选择排序<br>4. 希尔 Shell 排序<br>5. 快速排序<br>6. 归并排序<br>7. 堆排序<br>8. 线性排序算法<br>9. 自省排序<br>10. 间接排序<br>11. 计数排序<br>12. 基数排序<br>13. 桶排序<br>14. 外部排序 - k 路归并败者树<br>15. 外部排序 - 最佳归并树|||
|
||||
|递归与分治||1. 二分搜索/查找<br>2. 大整数的乘法<br>3. Strassen 矩阵乘法<br>4. 棋盘覆盖<br>5. 合并排序<br>6. 快速排序<br>7. 线性时间选择<br>8. 最接近点对问题<br>9. 循环赛日程表<br>||
|
||||
|动态规划||1. 矩阵连乘问题<br>2. 最长公共子序列<br>3. 最大子段和<br>4. 凸多边形最优三角剖分<br>5. 多边形游戏<br>6. 图像压缩<br>7. 电路布线<br>8. 流水作业调度<br>9. 0-1 背包问题/背包九讲<br>10. 最优二叉搜索树<br>11. 动态规划加速原理<br>12. 树型 DP<br>||
|
||||
|贪心||1. 活动安排问题<br>2. 最优装载<br>3. 哈夫曼编码<br>4. 单源最短路径<br>5. 最小生成树<br>6. 多机调度问题<br>||
|
||||
|回溯法||1. 装载问题<br>2. 批处理作业调度<br>3. 符号三角形问题<br>4. n 后问题<br>5. 0-1 背包问题<br>6. 最大团问题<br>7. 图的 m 着色问题<br>8. 旅行售货员问题<br>9. 圆排列问题<br>10. 电路板排列问题<br>11. 连续邮资问题<br>||
|
||||
|搜索|1. 枚举<br>2. DFS<br>3. BFS<br>4. 启发式搜索<br>|||
|
||||
|随机化|1. 随机数<br>2. 数值随机化算法<br>3. Sherwood 舍伍德算法<br>4. Las Vegas 拉斯维加斯算法<br>5. Monte Carlo 蒙特卡罗算法<br>|1. 计算 π 值<br>2. 计算定积分<br>3. 解非线性方程组<br>4. 线性时间选择算法<br>5. 跳跃表<br>6. n 后问题<br>7. 整数因子分解<br>8. 主元素问题<br>9. 素数测试<br>||
|
||||
|图论|1. 遍历 DFS / BFS<br>2. AOV / AOE 网络<br>3. Kruskal 算法(最小生成树)<br>4. Prim 算法(最小生成树)<br>5. Boruvka 算法(最小生成树)<br>6. Dijkstra 算法(单源最短路径)<br>7. Bellman-Ford 算法(单源最短路径)<br>8. SPFA 算法(单源最短路径)<br>9. Floyd 算法(多源最短路径)<br>10. Johnson 算法(多源最短路径)<br>11. Fleury 算法(欧拉回路)<br>12. Ford-Fulkerson 算法(最大网络流增广路)<br>13. Edmonds-Karp 算法(最大网络流)<br>14. Dinic 算法(最大网络流)<br>15. 一般预流推进算法<br>16. 最高标号预流推进 HLPP 算法<br>17. Primal-Dual 原始对偶算法(最小费用流)18. Kosaraju 算法(有向图强连通分量)<br>19. Tarjan 算法(有向图强连通分量)<br>20. Gabow 算法(有向图强连通分量)<br>21. 匈牙利算法(二分图匹配)<br>22. Hopcroft-Karp 算法(二分图匹配)<br>23. kuhn munkras 算法(二分图最佳匹配)<br>24. Edmonds’ Blossom-Contraction 算法(一般图匹配)<br>|1. 图遍历<br>2. 有向图和无向图的强弱连通性<br>3. 割点/割边<br>3. AOV 网络和拓扑排序<br>4. AOE 网络和关键路径<br>5. 最小代价生成树/次小生成树<br>6. 最短路径问题/第 K 短路问题<br>7. 最大网络流问题<br>8. 最小费用流问题<br>9. 图着色问题<br>10. 差分约束系统<br>11. 欧拉回路<br>12. 中国邮递员问题<br>13. 汉密尔顿回路<br>14. 最佳边割集/最佳点割集/最小边割集/最小点割集/最小路径覆盖/最小点集覆盖 <br>15. 边覆盖集<br>16. 二分图完美匹配和最大匹配问题<br>17. 仙人掌图<br>18. 弦图<br>19. 稳定婚姻问题<br>20. 最大团问题<br>||
|
||||
|数论||1. 最大公约数<br> 2. 最小公倍数<br>3. 分解质因数<br>4. 素数判定<br>5. 进制转换<br>6. 高精度计算<br>7. 整除问题<br>8. 同余问题<br>9. 欧拉函数<br>10. 扩展欧几里得<br>11. 置换群<br>12. 母函数<br>13. 离散变换<br>14. 康托展开<br>15. 矩阵<br>16. 向量<br>17. 线性方程组<br>18. 线性规划<br> ||
|
||||
|几何||1. 凸包 - Gift wrapping<br>2. 凸包 - Graham scan<br>3. 线段问题<br> 4. 多边形和多面体相关问题<br>||
|
||||
|NP 完全|1. 计算模型<br>2. P 类与 NP 类问题<br>3. NP 完全问题<br>4. NP 完全问题的近似算法<br>|1. 随机存取机 RAM<br>2. 随机存取存储程序机 RASP<br>3. 图灵机<br>4. 非确定性图灵机<br>5. P 类与 NP 类语言<br>6. 多项式时间验证<br>7. 多项式时间变换<br>8. Cook定理<br>9. 合取范式的可满足性问题 CNF-SAT<br>10. 3 元合取范式的可满足性问题 3-SAT<br>11. 团问题 CLIQUE<br>12. 顶点覆盖问题 VERTEX-COVER<br>13. 子集和问题 SUBSET-SUM<br>14. 哈密顿回路问题 HAM-CYCLE<br>15. 旅行售货员问题 TSP<br>16. 顶点覆盖问题的近似算法<br>17. 旅行售货员问题近似算法<br>18. 具有三角不等式性质的旅行售货员问题<br>19. 一般的旅行售货员问题<br>20. 集合覆盖问题的近似算法<br>21. 子集和问题的近似算法<br>22. 子集和问题的指数时间算法<br>23. 子集和问题的多项式时间近似格式<br>||
|
||||
|------------|------------------------------------------------------------------|-----------------------------------------------------------------|--------------------|
|
||||
|
||||
|
||||
## LeetCode Problems
|
||||
|
||||
## 一. 个人数据
|
||||
|
||||
{{.PersonalData}}
|
||||
|
||||
## 二. 目录
|
||||
|
||||
{{.TotalNum}}
|
||||
|
||||
{{.AvailableTable}}
|
||||
|
||||
------------------------------------------------------------------
|
||||
|
||||
下面这些是免费的算法题,但是暂时还不能使用 Go 解答的:
|
||||
|
||||
暂无
|
||||
|
||||
------------------------------------------------------------------
|
||||
|
||||
|
||||
## 三.分类
|
||||
|
||||
## Array
|
||||
|
||||
|
||||
Problems List in [there](https://books.halfrost.com/leetcode/ChapterTwo/Array/)
|
||||
|
||||
|
||||
|
||||
## String
|
||||
|
||||
Problems List in [there](https://books.halfrost.com/leetcode/ChapterTwo/String/)
|
||||
|
||||
|
||||
## Two Pointers
|
||||
|
||||

|
||||
|
||||
- 双指针滑动窗口的经典写法。右指针不断往右移,移动到不能往右移动为止(具体条件根据题目而定)。当右指针到最右边以后,开始挪动左指针,释放窗口左边界。第 3 题,第 76 题,第 209 题,第 424 题,第 438 题,第 567 题,第 713 题,第 763 题,第 845 题,第 881 题,第 904 题,第 978 题,第 992 题,第 1004 题,第 1040 题,第 1052 题。
|
||||
|
||||
```c
|
||||
left, right := 0, -1
|
||||
|
||||
for left < len(s) {
|
||||
if right+1 < len(s) && freq[s[right+1]-'a'] == 0 {
|
||||
freq[s[right+1]-'a']++
|
||||
right++
|
||||
} else {
|
||||
freq[s[left]-'a']--
|
||||
left++
|
||||
}
|
||||
result = max(result, right-left+1)
|
||||
}
|
||||
```
|
||||
|
||||
- 快慢指针可以查找重复数字,时间复杂度 O(n),第 287 题。
|
||||
- 替换字母以后,相同字母能出现连续最长的长度。第 424 题。
|
||||
- SUM 问题集。第 1 题,第 15 题,第 16 题,第 18 题,第 167 题,第 923 题,第 1074 题。
|
||||
|
||||
|
||||
Problems List in [there](https://books.halfrost.com/leetcode/ChapterTwo/Two_Pointers/)
|
||||
|
||||
|
||||
## Linked List
|
||||
|
||||

|
||||
|
||||
|
||||
- 巧妙的构造虚拟头结点。可以使遍历处理逻辑更加统一。
|
||||
- 灵活使用递归。构造递归条件,使用递归可以巧妙的解题。不过需要注意有些题目不能使用递归,因为递归深度太深会导致超时和栈溢出。
|
||||
- 链表区间逆序。第 92 题。
|
||||
- 链表寻找中间节点。第 876 题。链表寻找倒数第 n 个节点。第 19 题。只需要一次遍历就可以得到答案。
|
||||
- 合并 K 个有序链表。第 21 题,第 23 题。
|
||||
- 链表归类。第 86 题,第 328 题。
|
||||
- 链表排序,时间复杂度要求 O(n * log n),空间复杂度 O(1)。只有一种做法,归并排序,至顶向下归并。第 148 题。
|
||||
- 判断链表是否存在环,如果有环,输出环的交叉点的下标;判断 2 个链表是否有交叉点,如果有交叉点,输出交叉点。第 141 题,第 142 题,第 160 题。
|
||||
|
||||
|
||||
Problems List in [there](https://books.halfrost.com/leetcode/ChapterTwo/Linked_List/)
|
||||
|
||||
|
||||
|
||||
|
||||
## Stack
|
||||
|
||||

|
||||
|
||||
- 括号匹配问题及类似问题。第 20 题,第 921 题,第 1021 题。
|
||||
- 栈的基本 pop 和 push 操作。第 71 题,第 150 题,第 155 题,第 224 题,第 225 题,第 232 题,第 946 题,第 1047 题。
|
||||
- 利用栈进行编码问题。第 394 题,第 682 题,第 856 题,第 880 题。
|
||||
- **单调栈**。**利用栈维护一个单调递增或者递减的下标数组**。第 84 题,第 456 题,第 496 题,第 503 题,第 739 题,第 901 题,第 907 题,第 1019 题。
|
||||
|
||||
Problems List in [there](https://books.halfrost.com/leetcode/ChapterTwo/Stack/)
|
||||
|
||||
|
||||
|
||||
## Tree
|
||||
|
||||
|
||||
Problems List in [there](https://books.halfrost.com/leetcode/ChapterTwo/Tree/)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Dynamic Programming
|
||||
|
||||
Problems List in [there](https://books.halfrost.com/leetcode/ChapterTwo/Dynamic_Programming/)
|
||||
|
||||
|
||||
|
||||
## Backtracking
|
||||
|
||||

|
||||
|
||||
- 排列问题 Permutations。第 46 题,第 47 题。第 60 题,第 526 题,第 996 题。
|
||||
- 组合问题 Combination。第 39 题,第 40 题,第 77 题,第 216 题。
|
||||
- 排列和组合杂交问题。第 1079 题。
|
||||
- N 皇后终极解法(二进制解法)。第 51 题,第 52 题。
|
||||
- 数独问题。第 37 题。
|
||||
- 四个方向搜索。第 79 题,第 212 题,第 980 题。
|
||||
- 子集合问题。第 78 题,第 90 题。
|
||||
- Trie。第 208 题,第 211 题。
|
||||
- BFS 优化。第 126 题,第 127 题。
|
||||
- DFS 模板。(只是一个例子,不对应任何题)
|
||||
|
||||
```go
|
||||
func combinationSum2(candidates []int, target int) [][]int {
|
||||
if len(candidates) == 0 {
|
||||
return [][]int{}
|
||||
}
|
||||
c, res := []int{}, [][]int{}
|
||||
sort.Ints(candidates)
|
||||
findcombinationSum2(candidates, target, 0, c, &res)
|
||||
return res
|
||||
}
|
||||
|
||||
func findcombinationSum2(nums []int, target, index int, c []int, res *[][]int) {
|
||||
if target == 0 {
|
||||
b := make([]int, len(c))
|
||||
copy(b, c)
|
||||
*res = append(*res, b)
|
||||
return
|
||||
}
|
||||
for i := index; i < len(nums); i++ {
|
||||
if i > index && nums[i] == nums[i-1] { // 这里是去重的关键逻辑
|
||||
continue
|
||||
}
|
||||
if target >= nums[i] {
|
||||
c = append(c, nums[i])
|
||||
findcombinationSum2(nums, target-nums[i], i+1, c, res)
|
||||
c = c[:len(c)-1]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
- BFS 模板。(只是一个例子,不对应任何题)
|
||||
|
||||
```go
|
||||
func updateMatrix_BFS(matrix [][]int) [][]int {
|
||||
res := make([][]int, len(matrix))
|
||||
if len(matrix) == 0 || len(matrix[0]) == 0 {
|
||||
return res
|
||||
}
|
||||
queue := make([][]int, 0)
|
||||
for i, _ := range matrix {
|
||||
res[i] = make([]int, len(matrix[0]))
|
||||
for j, _ := range res[i] {
|
||||
if matrix[i][j] == 0 {
|
||||
res[i][j] = -1
|
||||
queue = append(queue, []int{i, j})
|
||||
}
|
||||
}
|
||||
}
|
||||
level := 1
|
||||
for len(queue) > 0 {
|
||||
size := len(queue)
|
||||
for size > 0 {
|
||||
size -= 1
|
||||
node := queue[0]
|
||||
queue = queue[1:]
|
||||
i, j := node[0], node[1]
|
||||
for _, direction := range [][]int{{-1, 0}, {1, 0}, {0, 1}, {0, -1}} {
|
||||
x := i + direction[0]
|
||||
y := j + direction[1]
|
||||
if x < 0 || x >= len(matrix) || y < 0 || y >= len(matrix[0]) || res[x][y] < 0 || res[x][y] > 0 {
|
||||
continue
|
||||
}
|
||||
res[x][y] = level
|
||||
queue = append(queue, []int{x, y})
|
||||
}
|
||||
}
|
||||
level++
|
||||
}
|
||||
for i, row := range res {
|
||||
for j, cell := range row {
|
||||
if cell == -1 {
|
||||
res[i][j] = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
return res
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
Problems List in [there](https://books.halfrost.com/leetcode/ChapterTwo/Backtracking/)
|
||||
|
||||
|
||||
## Depth First Search
|
||||
|
||||
|
||||
Problems List in [there](https://books.halfrost.com/leetcode/ChapterTwo/Depth_First_Search/)
|
||||
|
||||
|
||||
|
||||
|
||||
## Breadth First Search
|
||||
|
||||
|
||||
|
||||
Problems List in [there](https://books.halfrost.com/leetcode/ChapterTwo/Breadth_First_Search/)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Binary Search
|
||||
|
||||
![]()
|
||||
|
||||
- 二分搜索的经典写法。需要注意的三点:
|
||||
1. 循环退出条件,注意是 low <= high,而不是 low < high。
|
||||
2. mid 的取值,mid := low + (high-low)>>1
|
||||
3. low 和 high 的更新。low = mid + 1,high = mid - 1。
|
||||
|
||||
```go
|
||||
func binarySearchMatrix(nums []int, target int) int {
|
||||
low, high := 0, len(nums)-1
|
||||
for low <= high {
|
||||
mid := low + (high-low)>>1
|
||||
if nums[mid] == target {
|
||||
return mid
|
||||
} else if nums[mid] > target {
|
||||
high = mid - 1
|
||||
} else {
|
||||
low = mid + 1
|
||||
}
|
||||
}
|
||||
return -1
|
||||
}
|
||||
```
|
||||
|
||||
- 二分搜索的变种写法。有 4 个基本变种:
|
||||
1. 查找第一个与 target 相等的元素,时间复杂度 O(logn)
|
||||
2. 查找最后一个与 target 相等的元素,时间复杂度 O(logn)
|
||||
3. 查找第一个大于等于 target 的元素,时间复杂度 O(logn)
|
||||
4. 查找最后一个小于等于 target 的元素,时间复杂度 O(logn)
|
||||
|
||||
```go
|
||||
// 二分查找第一个与 target 相等的元素,时间复杂度 O(logn)
|
||||
func searchFirstEqualElement(nums []int, target int) int {
|
||||
low, high := 0, len(nums)-1
|
||||
for low <= high {
|
||||
mid := low + ((high - low) >> 1)
|
||||
if nums[mid] > target {
|
||||
high = mid - 1
|
||||
} else if nums[mid] < target {
|
||||
low = mid + 1
|
||||
} else {
|
||||
if (mid == 0) || (nums[mid-1] != target) { // 找到第一个与 target 相等的元素
|
||||
return mid
|
||||
}
|
||||
high = mid - 1
|
||||
}
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
// 二分查找最后一个与 target 相等的元素,时间复杂度 O(logn)
|
||||
func searchLastEqualElement(nums []int, target int) int {
|
||||
low, high := 0, len(nums)-1
|
||||
for low <= high {
|
||||
mid := low + ((high - low) >> 1)
|
||||
if nums[mid] > target {
|
||||
high = mid - 1
|
||||
} else if nums[mid] < target {
|
||||
low = mid + 1
|
||||
} else {
|
||||
if (mid == len(nums)-1) || (nums[mid+1] != target) { // 找到最后一个与 target 相等的元素
|
||||
return mid
|
||||
}
|
||||
low = mid + 1
|
||||
}
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
// 二分查找第一个大于等于 target 的元素,时间复杂度 O(logn)
|
||||
func searchFirstGreaterElement(nums []int, target int) int {
|
||||
low, high := 0, len(nums)-1
|
||||
for low <= high {
|
||||
mid := low + ((high - low) >> 1)
|
||||
if nums[mid] >= target {
|
||||
if (mid == 0) || (nums[mid-1] < target) { // 找到第一个大于等于 target 的元素
|
||||
return mid
|
||||
}
|
||||
high = mid - 1
|
||||
} else {
|
||||
low = mid + 1
|
||||
}
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
// 二分查找最后一个小于等于 target 的元素,时间复杂度 O(logn)
|
||||
func searchLastLessElement(nums []int, target int) int {
|
||||
low, high := 0, len(nums)-1
|
||||
for low <= high {
|
||||
mid := low + ((high - low) >> 1)
|
||||
if nums[mid] <= target {
|
||||
if (mid == len(nums)-1) || (nums[mid+1] > target) { // 找到最后一个小于等于 target 的元素
|
||||
return mid
|
||||
}
|
||||
low = mid + 1
|
||||
} else {
|
||||
high = mid - 1
|
||||
}
|
||||
}
|
||||
return -1
|
||||
}
|
||||
```
|
||||
|
||||
- 在基本有序的数组中用二分搜索。经典解法可以解,变种写法也可以写,常见的题型,在山峰数组中找山峰,在旋转有序数组中找分界点。第 33 题,第 81 题,第 153 题,第 154 题,第 162 题,第 852 题
|
||||
|
||||
```go
|
||||
func peakIndexInMountainArray(A []int) int {
|
||||
low, high := 0, len(A)-1
|
||||
for low < high {
|
||||
mid := low + (high-low)>>1
|
||||
// 如果 mid 较大,则左侧存在峰值,high = m,如果 mid + 1 较大,则右侧存在峰值,low = mid + 1
|
||||
if A[mid] > A[mid+1] {
|
||||
high = mid
|
||||
} else {
|
||||
low = mid + 1
|
||||
}
|
||||
}
|
||||
return low
|
||||
}
|
||||
```
|
||||
|
||||
- max-min 最大值最小化问题。求在最小满足条件的情况下的最大值。第 410 题,第 875 题,第 1011 题,第 1283 题。
|
||||
|
||||
Problems List in [there](https://books.halfrost.com/leetcode/ChapterTwo/Binary_Search/)
|
||||
|
||||
|
||||
|
||||
## Math
|
||||
|
||||
|
||||
Problems List in [there](https://books.halfrost.com/leetcode/ChapterTwo/Math/)
|
||||
|
||||
|
||||
|
||||
|
||||
## Hash Table
|
||||
|
||||
|
||||
Problems List in [there](https://books.halfrost.com/leetcode/ChapterTwo/Hash_Table/)
|
||||
|
||||
|
||||
|
||||
## Sort
|
||||
|
||||

|
||||
|
||||
- 深刻的理解多路快排。第 75 题。
|
||||
- 链表的排序,插入排序(第 147 题)和归并排序(第 148 题)
|
||||
- 桶排序和基数排序。第 164 题。
|
||||
- "摆动排序"。第 324 题。
|
||||
- 两两不相邻的排序。第 767 题,第 1054 题。
|
||||
- "饼子排序"。第 969 题。
|
||||
|
||||
Problems List in [there](https://books.halfrost.com/leetcode/ChapterTwo/Sort/)
|
||||
|
||||
|
||||
## Bit Manipulation
|
||||
|
||||

|
||||
|
||||
- 异或的特性。第 136 题,第 268 题,第 389 题,第 421 题,
|
||||
|
||||
```go
|
||||
x ^ 0 = x
|
||||
x ^ 11111……1111 = ~x
|
||||
x ^ (~x) = 11111……1111
|
||||
x ^ x = 0
|
||||
a ^ b = c => a ^ c = b => b ^ c = a (交换律)
|
||||
a ^ b ^ c = a ^ (b ^ c) = (a ^ b)^ c (结合律)
|
||||
```
|
||||
|
||||
- 构造特殊 Mask,将特殊位置放 0 或 1。
|
||||
|
||||
```go
|
||||
将 x 最右边的 n 位清零, x & ( ~0 << n )
|
||||
获取 x 的第 n 位值(0 或者 1),(x >> n) & 1
|
||||
获取 x 的第 n 位的幂值,x & (1 << (n - 1))
|
||||
仅将第 n 位置为 1,x | (1 << n)
|
||||
仅将第 n 位置为 0,x & (~(1 << n))
|
||||
将 x 最高位至第 n 位(含)清零,x & ((1 << n) - 1)
|
||||
将第 n 位至第 0 位(含)清零,x & (~((1 << (n + 1)) - 1))
|
||||
```
|
||||
|
||||
- 有特殊意义的 & 位操作运算。第 260 题,第 201 题,第 318 题,第 371 题,第 397 题,第 461 题,第 693 题,
|
||||
|
||||
```go
|
||||
X & 1 == 1 判断是否是奇数(偶数)
|
||||
X & = (X - 1) 将最低位(LSB)的 1 清零
|
||||
X & -X 得到最低位(LSB)的 1
|
||||
X & ~X = 0
|
||||
```
|
||||
|
||||
Problems List in [there](https://books.halfrost.com/leetcode/ChapterTwo/Bit_Manipulation/)
|
||||
|
||||
|
||||
## Union Find
|
||||
|
||||

|
||||
|
||||
- 灵活使用并查集的思想,熟练掌握并查集的[模板](https://github.com/halfrost/leetcode-go/blob/master/template/UnionFind.go),模板中有两种并查集的实现方式,一种是路径压缩 + 秩优化的版本,另外一种是计算每个集合中元素的个数 + 最大集合元素个数的版本,这两种版本都有各自使用的地方。能使用第一类并查集模板的题目有:第 128 题,第 130 题,第 547 题,第 684 题,第 721 题,第 765 题,第 778 题,第 839 题,第 924 题,第 928 题,第 947 题,第 952 题,第 959 题,第 990 题。能使用第二类并查集模板的题目有:第 803 题,第 952 题。第 803 题秩优化和统计集合个数这些地方会卡时间,如果不优化,会 TLE。
|
||||
- 并查集是一种思想,有些题需要灵活使用这种思想,而不是死套模板,如第 399 题,这一题是 stringUnionFind,利用并查集思想实现的。这里每个节点是基于字符串和 map 的,而不是单纯的用 int 节点编号实现的。
|
||||
- 有些题死套模板反而做不出来,比如第 685 题,这一题不能路径压缩和秩优化,因为题目中涉及到有向图,需要知道节点的前驱节点,如果路径压缩了,这一题就没法做了。这一题不需要路径压缩和秩优化。
|
||||
- 灵活的抽象题目给的信息,将给定的信息合理的编号,使用并查集解题,并用 map 降低时间复杂度,如第 721 题,第 959 题。
|
||||
- 关于地图,砖块,网格的题目,可以新建一个特殊节点,将四周边缘的砖块或者网格都 union() 到这个特殊节点上。第 130 题,第 803 题。
|
||||
- 能用并查集的题目,一般也可以用 DFS 和 BFS 解答,只不过时间复杂度会高一点。
|
||||
|
||||
|
||||
Problems List in [there](https://books.halfrost.com/leetcode/ChapterTwo/Union_Find/)
|
||||
|
||||
|
||||
|
||||
## Sliding Window
|
||||
|
||||

|
||||
|
||||
- 双指针滑动窗口的经典写法。右指针不断往右移,移动到不能往右移动为止(具体条件根据题目而定)。当右指针到最右边以后,开始挪动左指针,释放窗口左边界。第 3 题,第 76 题,第 209 题,第 424 题,第 438 题,第 567 题,第 713 题,第 763 题,第 845 题,第 881 题,第 904 题,第 978 题,第 992 题,第 1004 题,第 1040 题,第 1052 题。
|
||||
|
||||
```c
|
||||
left, right := 0, -1
|
||||
|
||||
for left < len(s) {
|
||||
if right+1 < len(s) && freq[s[right+1]-'a'] == 0 {
|
||||
freq[s[right+1]-'a']++
|
||||
right++
|
||||
} else {
|
||||
freq[s[left]-'a']--
|
||||
left++
|
||||
}
|
||||
result = max(result, right-left+1)
|
||||
}
|
||||
```
|
||||
- 滑动窗口经典题。第 239 题,第 480 题。
|
||||
|
||||
Problems List in [there](https://books.halfrost.com/leetcode/ChapterTwo/Sliding_Window/)
|
||||
|
||||
|
||||
## Segment Tree
|
||||
|
||||

|
||||
|
||||
- 线段树的经典数组实现写法。将合并两个节点 pushUp 逻辑抽象出来了,可以实现任意操作(常见的操作有:加法,取 max,min 等等)。第 218 题,第 303 题,第 307 题,第 699 题。
|
||||
- 计数线段树的经典写法。第 315 题,第 327 题,第 493 题。
|
||||
- 线段树的树的实现写法。第 715 题,第 732 题。
|
||||
- 区间懒惰更新。第 218 题,第 699 题。
|
||||
- 离散化。离散化需要注意一个特殊情况:假如三个区间为 [1,10] [1,4] [6,10],离散化后 x[1]=1,x[2]=4,x[3]=6,x[4]=10。第一个区间为 [1,4],第二个区间为 [1,2],第三个区间为 [3,4],这样一来,区间一 = 区间二 + 区间三,这和离散前的模型不符,离散前,很明显,区间一 > 区间二 + 区间三。正确的做法是:在相差大于 1 的数间加一个数,例如在上面 1 4 6 10 中间加 5,即可 x[1]=1,x[2]=4,x[3]=5,x[4]=6,x[5]=10。这样处理之后,区间一是 1-5 ,区间二是 1-2 ,区间三是 4-5 。
|
||||
- 灵活构建线段树。线段树节点可以存储多条信息,合并两个节点的 pushUp 操作也可以是多样的。第 850 题,第 1157 题。
|
||||
|
||||
|
||||
线段树[题型](https://blog.csdn.net/xuechelingxiao/article/details/38313105)从简单到困难:
|
||||
|
||||
1. 单点更新:
|
||||
[HDU 1166 敌兵布阵](http://acm.hdu.edu.cn/showproblem.php?pid=1166) update:单点增减 query:区间求和
|
||||
[HDU 1754 I Hate It](http://acm.hdu.edu.cn/showproblem.php?pid=1754) update:单点替换 query:区间最值
|
||||
[HDU 1394 Minimum Inversion Number](http://acm.hdu.edu.cn/showproblem.php?pid=1394) update:单点增减 query:区间求和
|
||||
[HDU 2795 Billboard](http://acm.hdu.edu.cn/showproblem.php?pid=2795) query:区间求最大值的位子(直接把update的操作在query里做了)
|
||||
2. 区间更新:
|
||||
[HDU 1698 Just a Hook](http://acm.hdu.edu.cn/showproblem.php?pid=1698) update:成段替换 (由于只query一次总区间,所以可以直接输出 1 结点的信息)
|
||||
[POJ 3468 A Simple Problem with Integers](http://poj.org/problem?id=3468) update:成段增减 query:区间求和
|
||||
[POJ 2528 Mayor’s posters](http://poj.org/problem?id=2528) 离散化 + update:成段替换 query:简单hash
|
||||
[POJ 3225 Help with Intervals](http://poj.org/problem?id=3225) update:成段替换,区间异或 query:简单hash
|
||||
3. 区间合并(这类题目会询问区间中满足条件的连续最长区间,所以PushUp的时候需要对左右儿子的区间进行合并):
|
||||
[POJ 3667 Hotel](http://poj.org/problem?id=3667) update:区间替换 query:询问满足条件的最左端点
|
||||
4. 扫描线(这类题目需要将一些操作排序,然后从左到右用一根扫描线扫过去最典型的就是矩形面积并,周长并等题):
|
||||
[HDU 1542 Atlantis](http://acm.hdu.edu.cn/showproblem.php?pid=1542) update:区间增减 query:直接取根节点的值
|
||||
[HDU 1828 Picture](http://acm.hdu.edu.cn/showproblem.php?pid=1828) update:区间增减 query:直接取根节点的值
|
||||
|
||||
Problems List in [there](https://books.halfrost.com/leetcode/ChapterTwo/Segment_Tree/)
|
||||
|
||||
|
||||
## Binary Indexed Tree
|
||||
|
||||

|
||||
|
||||
Problems List in [there](https://books.halfrost.com/leetcode/ChapterTwo/Binary_Indexed_Tree/)
|
||||
|
||||
|
||||
----------------------------------------------------------------------------------------
|
||||
|
||||
<p align='center'>
|
||||
<a href="https://github.com/halfrost/leetcode-go/releases/tag/Special"><img src="https://img.halfrost.com/Leetcode/ACM-ICPC_Algorithm_Template.png"></a>
|
||||
</p>
|
||||
|
||||
Thank you for reading here. This is bonus. You can download my [《ACM-ICPC Algorithm Template》](https://github.com/halfrost/leetcode-go/releases/tag/Special/)
|
||||
|
||||
|
||||
|
||||
## ♥️ Thanks
|
||||
|
||||
Thanks for your Star!
|
||||
|
||||
[](https://starchart.cc/halfrost/LeetCode-Go)
|
||||
|
36
ctl/template_render.go
Normal file
36
ctl/template_render.go
Normal file
@ -0,0 +1,36 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
)
|
||||
|
||||
func makeReadmeFile(mdrows Mdrows) {
|
||||
file := "./README.md"
|
||||
os.Remove(file)
|
||||
var b bytes.Buffer
|
||||
tmpl := template.Must(template.New("readme").Parse(readTMPL("template.markdown")))
|
||||
err := tmpl.Execute(&b, mdrows)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
// 保存 README.md 文件
|
||||
WriteFile(file, b.Bytes())
|
||||
}
|
||||
|
||||
func readTMPL(path string) string {
|
||||
file, err := os.Open(path)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
data, err := ioutil.ReadAll(file)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
return string(data)
|
||||
}
|
44
ctl/user.go
Normal file
44
ctl/user.go
Normal file
@ -0,0 +1,44 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// UserInfo define
|
||||
type UserInfo struct {
|
||||
UserName string `json:"user_name"`
|
||||
NumSolved int32 `json:"num_solved"`
|
||||
NumTotal int32 `json:"num_total"`
|
||||
AcEasy int32 `json:"ac_easy"`
|
||||
AcMedium int32 `json:"ac_medium"`
|
||||
AcHard int32 `json:"ac_hard"`
|
||||
EasyTotal int32
|
||||
MediumTotal int32
|
||||
HardTotal int32
|
||||
OptimizingEasy int32
|
||||
OptimizingMedium int32
|
||||
OptimizingHard int32
|
||||
FrequencyHigh float64 `json:"frequency_high"`
|
||||
FrequencyMid float64 `json:"frequency_mid"`
|
||||
CategorySlug string `json:"category_slug"`
|
||||
}
|
||||
|
||||
// | | Easy | Medium | Hard | Total | optimizing |
|
||||
// |:--------:|:--------------------------------------------------------------|:--------:|:--------:|:--------:|:--------:|
|
||||
func (ui UserInfo) table() string {
|
||||
res := "| | Easy | Medium | Hard | Total |\n"
|
||||
res += "|:--------:|:--------:|:--------:|:--------:|:--------:|\n"
|
||||
res += fmt.Sprintf("|Optimizing|%v|%v|%v|%v|\n", ui.OptimizingEasy, ui.OptimizingMedium, ui.OptimizingHard, ui.OptimizingEasy+ui.OptimizingMedium+ui.OptimizingHard)
|
||||
res += fmt.Sprintf("|Accepted|**%v**|**%v**|**%v**|**%v**|\n", ui.AcEasy, ui.AcMedium, ui.AcHard, ui.AcEasy+ui.AcMedium+ui.AcHard)
|
||||
res += fmt.Sprintf("|Total|%v|%v|%v|%v|\n", ui.EasyTotal, ui.MediumTotal, ui.HardTotal, ui.EasyTotal+ui.MediumTotal+ui.HardTotal)
|
||||
res += fmt.Sprintf("|Perfection Rate|%.1f%%|%.1f%%|%.1f%%|%.1f%%|\n", (1-float64(ui.OptimizingEasy)/float64(ui.AcEasy))*100, (1-float64(ui.OptimizingMedium)/float64(ui.AcMedium))*100, (1-float64(ui.OptimizingHard)/float64(ui.AcHard))*100, (1-float64(ui.OptimizingEasy+ui.OptimizingMedium+ui.OptimizingHard)/float64(ui.AcEasy+ui.AcMedium+ui.AcHard))*100)
|
||||
res += fmt.Sprintf("|Completion Rate|%.1f%%|%.1f%%|%.1f%%|%.1f%%|\n", float64(ui.AcEasy)/float64(ui.EasyTotal)*100, float64(ui.AcMedium)/float64(ui.MediumTotal)*100, float64(ui.AcHard)/float64(ui.HardTotal)*100, float64(ui.AcEasy+ui.AcMedium+ui.AcHard)/float64(ui.EasyTotal+ui.MediumTotal+ui.HardTotal)*100)
|
||||
// 加这一行是为了撑开整个表格
|
||||
res += "|------------|----------------------------|----------------------------|----------------------------|----------------------------|"
|
||||
return res
|
||||
}
|
||||
|
||||
// PersonalData define
|
||||
func (ui UserInfo) PersonalData() string {
|
||||
return ui.table()
|
||||
}
|
185
ctl/util.go
Normal file
185
ctl/util.go
Normal file
@ -0,0 +1,185 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// LoadSolutionsDir define
|
||||
func LoadSolutionsDir() ([]int, []string, int) {
|
||||
solutionIds, soNames, total := loadFile("../leetcode/")
|
||||
fmt.Printf("读取了 %v 道题的题解,当前目录下有 %v 个文件(可能包含 .DS_Store),目录中有 %v 道题在尝试中\n", len(solutionIds), total, total-len(solutionIds))
|
||||
return solutionIds, soNames, total - len(solutionIds)
|
||||
}
|
||||
|
||||
func loadFile(path string) ([]int, []string, int) {
|
||||
files, err := ioutil.ReadDir(path)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
solutionIds, soNames, solutionsMap := []int{}, []string{}, map[int]string{}
|
||||
for _, f := range files {
|
||||
if f.Name()[4] == '.' {
|
||||
tmp, err := strconv.Atoi(f.Name()[:4])
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
solutionIds = append(solutionIds, tmp)
|
||||
solutionsMap[tmp] = f.Name()
|
||||
}
|
||||
}
|
||||
sort.Ints(solutionIds)
|
||||
for _, v := range solutionIds {
|
||||
if name, ok := solutionsMap[v]; ok {
|
||||
soNames = append(soNames, name)
|
||||
}
|
||||
}
|
||||
return solutionIds, soNames, len(files)
|
||||
}
|
||||
|
||||
// GetAllFile define
|
||||
func GetAllFile(pathname string, fileList *[]string) ([]string, error) {
|
||||
rd, err := ioutil.ReadDir(pathname)
|
||||
for _, fi := range rd {
|
||||
if fi.IsDir() {
|
||||
//fmt.Printf("[%s]\n", pathname+"\\"+fi.Name())
|
||||
GetAllFile(pathname+fi.Name()+"/", fileList)
|
||||
} else {
|
||||
//fmt.Println(fi.Name())
|
||||
*fileList = append(*fileList, fi.Name())
|
||||
}
|
||||
}
|
||||
return *fileList, err
|
||||
}
|
||||
|
||||
// LoadChapterFourDir define
|
||||
func LoadChapterFourDir() ([]string, []int) {
|
||||
files, err := GetAllFile("../website/content/ChapterFour/", &[]string{})
|
||||
// files, err := ioutil.ReadDir("../website/content/ChapterFour/")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
solutions, solutionIds, solutionsMap := []string{}, []int{}, map[int]string{}
|
||||
for _, f := range files {
|
||||
if f[4] == '.' {
|
||||
tmp, err := strconv.Atoi(f[:4])
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
solutionIds = append(solutionIds, tmp)
|
||||
// len(f.Name())-3 = 文件名去掉 .md 后缀
|
||||
solutionsMap[tmp] = f[:len(f)-3]
|
||||
}
|
||||
}
|
||||
sort.Ints(solutionIds)
|
||||
fmt.Printf("读取了第四章的 %v 道题的题解\n", len(solutionIds))
|
||||
for _, v := range solutionIds {
|
||||
if name, ok := solutionsMap[v]; ok {
|
||||
solutions = append(solutions, name)
|
||||
}
|
||||
}
|
||||
return solutions, solutionIds
|
||||
}
|
||||
|
||||
// WriteFile define
|
||||
func WriteFile(fileName string, content []byte) {
|
||||
file, err := os.OpenFile(fileName, os.O_RDWR|os.O_CREATE, 0777)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
_, err = file.Write(content)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
//fmt.Println("write file successful")
|
||||
}
|
||||
|
||||
// LoadFile define
|
||||
func LoadFile(filePath string) ([]byte, error) {
|
||||
f, err := os.OpenFile(filePath, os.O_RDONLY, 0644)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer f.Close()
|
||||
reader, output := bufio.NewReader(f), []byte{}
|
||||
for {
|
||||
line, _, err := reader.ReadLine()
|
||||
if err != nil {
|
||||
if err == io.EOF {
|
||||
return output, nil
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
output = append(output, line...)
|
||||
output = append(output, []byte("\n")...)
|
||||
}
|
||||
}
|
||||
|
||||
// DestoryDir define
|
||||
func DestoryDir(path string) {
|
||||
filepath.Walk(path, func(path string, fi os.FileInfo, err error) error {
|
||||
if nil == fi {
|
||||
return err
|
||||
}
|
||||
if !fi.IsDir() {
|
||||
return nil
|
||||
}
|
||||
name := fi.Name()
|
||||
if strings.Contains(name, "temp") {
|
||||
fmt.Println("temp file name:", path)
|
||||
err := os.RemoveAll(path)
|
||||
if err != nil {
|
||||
fmt.Println("delet dir error:", err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
// CopyFile define
|
||||
func CopyFile(dstName, srcName string) (written int64, err error) {
|
||||
src, err := os.Open(srcName)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer src.Close()
|
||||
dst, err := os.OpenFile(dstName, os.O_WRONLY|os.O_CREATE, 0644)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer dst.Close()
|
||||
return io.Copy(dst, src)
|
||||
}
|
||||
|
||||
// BinarySearch define
|
||||
func BinarySearch(nums []int, target int) int {
|
||||
low, high := 0, len(nums)-1
|
||||
for low <= high {
|
||||
mid := low + (high-low)>>1
|
||||
if nums[mid] == target {
|
||||
return mid
|
||||
} else if nums[mid] > target {
|
||||
high = mid - 1
|
||||
} else {
|
||||
low = mid + 1
|
||||
}
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
// GetChpaterFourFileNum define
|
||||
func GetChpaterFourFileNum(num int) string {
|
||||
if num < 100 {
|
||||
return fmt.Sprintf("%04d~%04d", (num/100)*100+1, (num/100)*100+99)
|
||||
}
|
||||
return fmt.Sprintf("%04d~%04d", (num/100)*100, (num/100)*100+99)
|
||||
}
|
18
ctl/version.go
Normal file
18
ctl/version.go
Normal file
@ -0,0 +1,18 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var (
|
||||
version = "v1.0"
|
||||
versionCmd = &cobra.Command{
|
||||
Use: "version",
|
||||
Short: "Prints the version of tacoctl",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
fmt.Println("tacoctl version:", version)
|
||||
},
|
||||
}
|
||||
)
|
24
go.mod
Normal file
24
go.mod
Normal file
@ -0,0 +1,24 @@
|
||||
module github.com/halfrost/LeetCode-Go
|
||||
|
||||
go 1.19
|
||||
|
||||
replace github.com/halfrost/LeetCode-Go/structures => ./structures
|
||||
|
||||
replace github.com/halfrost/LeetCode-Go/template => ./template
|
||||
|
||||
require (
|
||||
github.com/BurntSushi/toml v1.2.0
|
||||
github.com/halfrost/LeetCode-Go/structures v0.0.0-20220910233101-aa0e2c897b18
|
||||
github.com/halfrost/LeetCode-Go/template v0.0.0-20220910233504-e2a72e6212ce
|
||||
github.com/mozillazg/request v0.8.0
|
||||
github.com/spf13/cobra v1.5.0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/bitly/go-simplejson v0.5.0 // indirect
|
||||
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.0.0 // indirect
|
||||
github.com/kr/pretty v0.3.0 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
golang.org/x/net v0.0.0-20220909164309-bea034e7d591 // indirect
|
||||
)
|
36
go.sum
Normal file
36
go.sum
Normal file
@ -0,0 +1,36 @@
|
||||
github.com/BurntSushi/toml v1.2.0 h1:Rt8g24XnyGTyglgET/PRUNlrUeu9F5L+7FilkXfZgs0=
|
||||
github.com/BurntSushi/toml v1.2.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
||||
github.com/bitly/go-simplejson v0.5.0 h1:6IH+V8/tVMab511d5bn4M7EwGXZf9Hj6i2xSwkNEM+Y=
|
||||
github.com/bitly/go-simplejson v0.5.0/go.mod h1:cXHtHw4XUPsvGaxgjIAn8PhEWG9NfngEKAMDJEczWVA=
|
||||
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4YnC6+E63dPcxHo2sUxDIu8g3QgEJdRY=
|
||||
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
|
||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
|
||||
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/mozillazg/request v0.8.0 h1:TbXeQUdBWr1J1df5Z+lQczDFzX9JD71kTCl7Zu/9rNM=
|
||||
github.com/mozillazg/request v0.8.0/go.mod h1:weoQ/mVFNbWgRBtivCGF1tUT9lwneFesues+CleXMWc=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k=
|
||||
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/spf13/cobra v1.5.0 h1:X+jTBEBqF0bHN+9cSMgmfuvv2VHJ9ezmFNf9Y/XstYU=
|
||||
github.com/spf13/cobra v1.5.0/go.mod h1:dWXEIy2H428czQCjInthrTRUg7yKbok+2Qi/yBIJoUM=
|
||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
|
||||
golang.org/x/net v0.0.0-20220909164309-bea034e7d591 h1:D0B/7al0LLrVC8aWF4+oxpv/m8bc7ViFfVS8/gXGdqI=
|
||||
golang.org/x/net v0.0.0-20220909164309-bea034e7d591/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
@ -26,32 +26,30 @@ type ans1 struct {
|
||||
func Test_Problem1(t *testing.T) {
|
||||
|
||||
qs := []question1{
|
||||
|
||||
question1{
|
||||
{
|
||||
para1{[]int{3, 2, 4}, 6},
|
||||
ans1{[]int{1, 2}},
|
||||
},
|
||||
|
||||
question1{
|
||||
{
|
||||
para1{[]int{3, 2, 4}, 5},
|
||||
ans1{[]int{0, 1}},
|
||||
},
|
||||
|
||||
question1{
|
||||
{
|
||||
para1{[]int{0, 8, 7, 3, 3, 4, 2}, 11},
|
||||
ans1{[]int{1, 3}},
|
||||
},
|
||||
|
||||
question1{
|
||||
{
|
||||
para1{[]int{0, 1}, 1},
|
||||
ans1{[]int{0, 1}},
|
||||
},
|
||||
|
||||
question1{
|
||||
{
|
||||
para1{[]int{0, 3}, 5},
|
||||
ans1{[]int{}},
|
||||
},
|
||||
|
||||
// 如需多个测试,可以复制上方元素。
|
||||
}
|
||||
|
||||
|
@ -16,36 +16,24 @@ type ListNode = structures.ListNode
|
||||
*/
|
||||
|
||||
func addTwoNumbers(l1 *ListNode, l2 *ListNode) *ListNode {
|
||||
if l1 == nil || l2 == nil {
|
||||
return nil
|
||||
}
|
||||
head := &ListNode{Val: 0, Next: nil}
|
||||
current := head
|
||||
carry := 0
|
||||
for l1 != nil || l2 != nil {
|
||||
var x, y int
|
||||
head := &ListNode{Val: 0}
|
||||
n1, n2, carry, current := 0, 0, 0, head
|
||||
for l1 != nil || l2 != nil || carry != 0 {
|
||||
if l1 == nil {
|
||||
x = 0
|
||||
n1 = 0
|
||||
} else {
|
||||
x = l1.Val
|
||||
}
|
||||
if l2 == nil {
|
||||
y = 0
|
||||
} else {
|
||||
y = l2.Val
|
||||
}
|
||||
current.Next = &ListNode{Val: (x + y + carry) % 10, Next: nil}
|
||||
current = current.Next
|
||||
carry = (x + y + carry) / 10
|
||||
if l1 != nil {
|
||||
n1 = l1.Val
|
||||
l1 = l1.Next
|
||||
}
|
||||
if l2 != nil {
|
||||
if l2 == nil {
|
||||
n2 = 0
|
||||
} else {
|
||||
n2 = l2.Val
|
||||
l2 = l2.Next
|
||||
}
|
||||
}
|
||||
if carry > 0 {
|
||||
current.Next = &ListNode{Val: carry % 10, Next: nil}
|
||||
current.Next = &ListNode{Val: (n1 + n2 + carry) % 10}
|
||||
current = current.Next
|
||||
carry = (n1 + n2 + carry) / 10
|
||||
}
|
||||
return head.Next
|
||||
}
|
||||
|
@ -29,42 +29,42 @@ func Test_Problem2(t *testing.T) {
|
||||
|
||||
qs := []question2{
|
||||
|
||||
question2{
|
||||
{
|
||||
para2{[]int{}, []int{}},
|
||||
ans2{[]int{}},
|
||||
},
|
||||
|
||||
question2{
|
||||
{
|
||||
para2{[]int{1}, []int{1}},
|
||||
ans2{[]int{2}},
|
||||
},
|
||||
|
||||
question2{
|
||||
{
|
||||
para2{[]int{1, 2, 3, 4}, []int{1, 2, 3, 4}},
|
||||
ans2{[]int{2, 4, 6, 8}},
|
||||
},
|
||||
|
||||
question2{
|
||||
{
|
||||
para2{[]int{1, 2, 3, 4, 5}, []int{1, 2, 3, 4, 5}},
|
||||
ans2{[]int{2, 4, 6, 8, 0, 1}},
|
||||
},
|
||||
|
||||
question2{
|
||||
{
|
||||
para2{[]int{1}, []int{9, 9, 9, 9, 9}},
|
||||
ans2{[]int{0, 0, 0, 0, 0, 1}},
|
||||
},
|
||||
|
||||
question2{
|
||||
{
|
||||
para2{[]int{9, 9, 9, 9, 9}, []int{1}},
|
||||
ans2{[]int{0, 0, 0, 0, 0, 1}},
|
||||
},
|
||||
|
||||
question2{
|
||||
{
|
||||
para2{[]int{2, 4, 3}, []int{5, 6, 4}},
|
||||
ans2{[]int{7, 0, 8}},
|
||||
},
|
||||
|
||||
question2{
|
||||
{
|
||||
para2{[]int{1, 8, 3}, []int{7, 1}},
|
||||
ans2{[]int{8, 9, 3}},
|
||||
},
|
||||
|
@ -8,7 +8,7 @@ func lengthOfLongestSubstring(s string) int {
|
||||
var bitSet [256]bool
|
||||
result, left, right := 0, 0, 0
|
||||
for left < len(s) {
|
||||
// 右侧字符对应的bitSet被标记true,说明此字符在X位置重复,需要左侧向前移动,直到将X标记为false
|
||||
// 右侧字符对应的 bitSet 被标记 true,说明此字符在 X 位置重复,需要左侧向前移动,直到将 X 标记为 false
|
||||
if bitSet[s[right]] {
|
||||
bitSet[s[left]] = false
|
||||
left++
|
||||
@ -27,19 +27,20 @@ func lengthOfLongestSubstring(s string) int {
|
||||
}
|
||||
|
||||
// 解法二 滑动窗口
|
||||
func lengthOfLongestSubstring_(s string) int {
|
||||
func lengthOfLongestSubstring1(s string) int {
|
||||
if len(s) == 0 {
|
||||
return 0
|
||||
}
|
||||
var freq [256]int
|
||||
var freq [127]int
|
||||
result, left, right := 0, 0, -1
|
||||
|
||||
for left < len(s) {
|
||||
if right+1 < len(s) && freq[s[right+1]-'a'] == 0 {
|
||||
freq[s[right+1]-'a']++
|
||||
if right+1 < len(s) && freq[s[right+1]] == 0 {
|
||||
freq[s[right+1]]++
|
||||
right++
|
||||
|
||||
} else {
|
||||
freq[s[left]-'a']--
|
||||
freq[s[left]]--
|
||||
left++
|
||||
}
|
||||
result = max(result, right-left+1)
|
||||
@ -47,6 +48,21 @@ func lengthOfLongestSubstring_(s string) int {
|
||||
return result
|
||||
}
|
||||
|
||||
// 解法三 滑动窗口-哈希桶
|
||||
func lengthOfLongestSubstring2(s string) int {
|
||||
right, left, res := 0, 0, 0
|
||||
indexes := make(map[byte]int, len(s))
|
||||
for left < len(s) {
|
||||
if idx, ok := indexes[s[left]]; ok && idx >= right {
|
||||
right = idx + 1
|
||||
}
|
||||
indexes[s[left]] = left
|
||||
left++
|
||||
res = max(res, left-right)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func max(a int, b int) int {
|
||||
if a > b {
|
||||
return a
|
||||
|
@ -26,22 +26,22 @@ func Test_Problem3(t *testing.T) {
|
||||
|
||||
qs := []question3{
|
||||
|
||||
question3{
|
||||
{
|
||||
para3{"abcabcbb"},
|
||||
ans3{3},
|
||||
},
|
||||
|
||||
question3{
|
||||
{
|
||||
para3{"bbbbb"},
|
||||
ans3{1},
|
||||
},
|
||||
|
||||
question3{
|
||||
{
|
||||
para3{"pwwkew"},
|
||||
ans3{3},
|
||||
},
|
||||
|
||||
question3{
|
||||
{
|
||||
para3{""},
|
||||
ans3{0},
|
||||
},
|
||||
@ -51,7 +51,7 @@ func Test_Problem3(t *testing.T) {
|
||||
|
||||
for _, q := range qs {
|
||||
_, p := q.ans3, q.para3
|
||||
fmt.Printf("【input】:%v 【output】:%v\n", p, lengthOfLongestSubstring_(p.s))
|
||||
fmt.Printf("【input】:%v 【output】:%v\n", p, lengthOfLongestSubstring(p.s))
|
||||
}
|
||||
fmt.Printf("\n\n\n")
|
||||
}
|
||||
|
@ -27,12 +27,12 @@ func Test_Problem4(t *testing.T) {
|
||||
|
||||
qs := []question4{
|
||||
|
||||
question4{
|
||||
{
|
||||
para4{[]int{1, 3}, []int{2}},
|
||||
ans4{2.0},
|
||||
},
|
||||
|
||||
question4{
|
||||
{
|
||||
para4{[]int{1, 2}, []int{3, 4}},
|
||||
ans4{2.5},
|
||||
},
|
||||
|
@ -39,7 +39,7 @@ You may assume **nums1** and **nums2** cannot be both empty.
|
||||
|
||||
|
||||
- 给出两个有序数组,要求找出这两个数组合并以后的有序数组中的中位数。要求时间复杂度为 O(log (m+n))。
|
||||
- 这一题最容易想到的办法是把两个数组合并,然后取出中位数。但是合并有序数组的操作是 `O(max(n,m))` 的,不符合题意。看到题目给的 `log` 的时间复杂度,很容易联想到二分搜索。
|
||||
- 这一题最容易想到的办法是把两个数组合并,然后取出中位数。但是合并有序数组的操作是 `O(m+n)` 的,不符合题意。看到题目给的 `log` 的时间复杂度,很容易联想到二分搜索。
|
||||
- 由于要找到最终合并以后数组的中位数,两个数组的总大小也知道,所以中间这个位置也是知道的。只需要二分搜索一个数组中切分的位置,另一个数组中切分的位置也能得到。为了使得时间复杂度最小,所以二分搜索两个数组中长度较小的那个数组。
|
||||
- 关键的问题是如何切分数组 1 和数组 2 。其实就是如何切分数组 1 。先随便二分产生一个 `midA`,切分的线何时算满足了中位数的条件呢?即,线左边的数都小于右边的数,即,`nums1[midA-1] ≤ nums2[midB] && nums2[midB-1] ≤ nums1[midA]` 。如果这些条件都不满足,切分线就需要调整。如果 `nums1[midA] < nums2[midB-1]`,说明 `midA` 这条线划分出来左边的数小了,切分线应该右移;如果 `nums1[midA-1] > nums2[midB]`,说明 midA 这条线划分出来左边的数大了,切分线应该左移。经过多次调整以后,切分线总能找到满足条件的解。
|
||||
- 假设现在找到了切分的两条线了,`数组 1` 在切分线两边的下标分别是 `midA - 1` 和 `midA`。`数组 2` 在切分线两边的下标分别是 `midB - 1` 和 `midB`。最终合并成最终数组,如果数组长度是奇数,那么中位数就是 `max(nums1[midA-1], nums2[midB-1])`。如果数组长度是偶数,那么中间位置的两个数依次是:`max(nums1[midA-1], nums2[midB-1])` 和 `min(nums1[midA], nums2[midB])`,那么中位数就是 `(max(nums1[midA-1], nums2[midB-1]) + min(nums1[midA], nums2[midB])) / 2`。图示见下图:
|
||||
|
@ -0,0 +1,117 @@
|
||||
package leetcode
|
||||
|
||||
// 解法一 Manacher's algorithm,时间复杂度 O(n),空间复杂度 O(n)
|
||||
func longestPalindrome(s string) string {
|
||||
if len(s) < 2 {
|
||||
return s
|
||||
}
|
||||
newS := make([]rune, 0)
|
||||
newS = append(newS, '#')
|
||||
for _, c := range s {
|
||||
newS = append(newS, c)
|
||||
newS = append(newS, '#')
|
||||
}
|
||||
// dp[i]: 以预处理字符串下标 i 为中心的回文半径(奇数长度时不包括中心)
|
||||
// maxRight: 通过中心扩散的方式能够扩散的最右边的下标
|
||||
// center: 与 maxRight 对应的中心字符的下标
|
||||
// maxLen: 记录最长回文串的半径
|
||||
// begin: 记录最长回文串在起始串 s 中的起始下标
|
||||
dp, maxRight, center, maxLen, begin := make([]int, len(newS)), 0, 0, 1, 0
|
||||
for i := 0; i < len(newS); i++ {
|
||||
if i < maxRight {
|
||||
// 这一行代码是 Manacher 算法的关键所在
|
||||
dp[i] = min(maxRight-i, dp[2*center-i])
|
||||
}
|
||||
// 中心扩散法更新 dp[i]
|
||||
left, right := i-(1+dp[i]), i+(1+dp[i])
|
||||
for left >= 0 && right < len(newS) && newS[left] == newS[right] {
|
||||
dp[i]++
|
||||
left--
|
||||
right++
|
||||
}
|
||||
// 更新 maxRight,它是遍历过的 i 的 i + dp[i] 的最大者
|
||||
if i+dp[i] > maxRight {
|
||||
maxRight = i + dp[i]
|
||||
center = i
|
||||
}
|
||||
// 记录最长回文子串的长度和相应它在原始字符串中的起点
|
||||
if dp[i] > maxLen {
|
||||
maxLen = dp[i]
|
||||
begin = (i - maxLen) / 2 // 这里要除以 2 因为有我们插入的辅助字符 #
|
||||
}
|
||||
}
|
||||
return s[begin : begin+maxLen]
|
||||
}
|
||||
|
||||
func min(x, y int) int {
|
||||
if x < y {
|
||||
return x
|
||||
}
|
||||
return y
|
||||
}
|
||||
|
||||
// 解法二 滑动窗口,时间复杂度 O(n^2),空间复杂度 O(1)
|
||||
func longestPalindrome1(s string) string {
|
||||
if len(s) == 0 {
|
||||
return ""
|
||||
}
|
||||
left, right, pl, pr := 0, -1, 0, 0
|
||||
for left < len(s) {
|
||||
// 移动到相同字母的最右边(如果有相同字母)
|
||||
for right+1 < len(s) && s[left] == s[right+1] {
|
||||
right++
|
||||
}
|
||||
// 找到回文的边界
|
||||
for left-1 >= 0 && right+1 < len(s) && s[left-1] == s[right+1] {
|
||||
left--
|
||||
right++
|
||||
}
|
||||
if right-left > pr-pl {
|
||||
pl, pr = left, right
|
||||
}
|
||||
// 重置到下一次寻找回文的中心
|
||||
left = (left+right)/2 + 1
|
||||
right = left
|
||||
}
|
||||
return s[pl : pr+1]
|
||||
}
|
||||
|
||||
// 解法三 中心扩散法,时间复杂度 O(n^2),空间复杂度 O(1)
|
||||
func longestPalindrome2(s string) string {
|
||||
res := ""
|
||||
for i := 0; i < len(s); i++ {
|
||||
res = maxPalindrome(s, i, i, res)
|
||||
res = maxPalindrome(s, i, i+1, res)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func maxPalindrome(s string, i, j int, res string) string {
|
||||
sub := ""
|
||||
for i >= 0 && j < len(s) && s[i] == s[j] {
|
||||
sub = s[i : j+1]
|
||||
i--
|
||||
j++
|
||||
}
|
||||
if len(res) < len(sub) {
|
||||
return sub
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
// 解法四 DP,时间复杂度 O(n^2),空间复杂度 O(n^2)
|
||||
func longestPalindrome3(s string) string {
|
||||
res, dp := "", make([][]bool, len(s))
|
||||
for i := 0; i < len(s); i++ {
|
||||
dp[i] = make([]bool, len(s))
|
||||
}
|
||||
for i := len(s) - 1; i >= 0; i-- {
|
||||
for j := i; j < len(s); j++ {
|
||||
dp[i][j] = (s[i] == s[j]) && ((j-i < 3) || dp[i+1][j-1])
|
||||
if dp[i][j] && (res == "" || j-i+1 > len(res)) {
|
||||
res = s[i : j+1]
|
||||
}
|
||||
}
|
||||
}
|
||||
return res
|
||||
}
|
@ -0,0 +1,67 @@
|
||||
package leetcode
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type question5 struct {
|
||||
para5
|
||||
ans5
|
||||
}
|
||||
|
||||
// para 是参数
|
||||
// one 代表第一个参数
|
||||
type para5 struct {
|
||||
s string
|
||||
}
|
||||
|
||||
// ans 是答案
|
||||
// one 代表第一个答案
|
||||
type ans5 struct {
|
||||
one string
|
||||
}
|
||||
|
||||
func Test_Problem5(t *testing.T) {
|
||||
|
||||
qs := []question5{
|
||||
|
||||
{
|
||||
para5{"babad"},
|
||||
ans5{"bab"},
|
||||
},
|
||||
|
||||
{
|
||||
para5{"cbbd"},
|
||||
ans5{"bb"},
|
||||
},
|
||||
|
||||
{
|
||||
para5{"a"},
|
||||
ans5{"a"},
|
||||
},
|
||||
|
||||
{
|
||||
para5{"ac"},
|
||||
ans5{"a"},
|
||||
},
|
||||
|
||||
{
|
||||
para5{"aa"},
|
||||
ans5{"aa"},
|
||||
},
|
||||
|
||||
{
|
||||
para5{"ajgiljtperkvubjmdsefcylksrxtftqrehoitdgdtttswwttmfuvwgwrruuqmxttzsbmuhgfaoueumvbhajqsaxkkihjwevzzedizmrsmpxqavyryklbotwzngxscvyuqjkkaotitddlhhnutmotupwuwyltebtsdfssbwayuxrbgihmtphshdslktvsjadaykyjivbzhwujcdvzdxxfiixnzrmusqvwujjmxhbqbdpauacnzojnzxxgrkmupadfcsujkcwajsgintahwgbjnvjqubcxajdyyapposrkpqtpqfjcvbhlmwfutgognqxgaukpmdyaxghgoqkqnigcllachmwzrazwhpppmsodvxilrccfqgpkmdqhoorxpyjsrtbeeidsinpeyxxpsjnymxkouskyhenzgieybwkgzrhhrzgkwbyeigznehyksuokxmynjspxxyepnisdieebtrsjypxroohqdmkpgqfccrlixvdosmppphwzarzwmhcallcginqkqoghgxaydmpkuagxqngogtufwmlhbvcjfqptqpkrsoppayydjaxcbuqjvnjbgwhatnigsjawckjuscfdapumkrgxxznjozncauapdbqbhxmjjuwvqsumrznxiifxxdzvdcjuwhzbvijykyadajsvtklsdhshptmhigbrxuyawbssfdstbetlywuwputomtunhhlddtitoakkjquyvcsxgnzwtoblkyryvaqxpmsrmzidezzvewjhikkxasqjahbvmueuoafghumbszttxmquurrwgwvufmttwwstttdgdtioherqtftxrsklycfesdmjbuvkreptjligja"},
|
||||
ans5{"ajgiljtperkvubjmdsefcylksrxtftqrehoitdgdtttswwttmfuvwgwrruuqmxttzsbmuhgfaoueumvbhajqsaxkkihjwevzzedizmrsmpxqavyryklbotwzngxscvyuqjkkaotitddlhhnutmotupwuwyltebtsdfssbwayuxrbgihmtphshdslktvsjadaykyjivbzhwujcdvzdxxfiixnzrmusqvwujjmxhbqbdpauacnzojnzxxgrkmupadfcsujkcwajsgintahwgbjnvjqubcxajdyyapposrkpqtpqfjcvbhlmwfutgognqxgaukpmdyaxghgoqkqnigcllachmwzrazwhpppmsodvxilrccfqgpkmdqhoorxpyjsrtbeeidsinpeyxxpsjnymxkouskyhenzgieybwkgzrhhrzgkwbyeigznehyksuokxmynjspxxyepnisdieebtrsjypxroohqdmkpgqfccrlixvdosmppphwzarzwmhcallcginqkqoghgxaydmpkuagxqngogtufwmlhbvcjfqptqpkrsoppayydjaxcbuqjvnjbgwhatnigsjawckjuscfdapumkrgxxznjozncauapdbqbhxmjjuwvqsumrznxiifxxdzvdcjuwhzbvijykyadajsvtklsdhshptmhigbrxuyawbssfdstbetlywuwputomtunhhlddtitoakkjquyvcsxgnzwtoblkyryvaqxpmsrmzidezzvewjhikkxasqjahbvmueuoafghumbszttxmquurrwgwvufmttwwstttdgdtioherqtftxrsklycfesdmjbuvkreptjligja"},
|
||||
},
|
||||
}
|
||||
|
||||
fmt.Printf("------------------------Leetcode Problem 5------------------------\n")
|
||||
|
||||
for _, q := range qs {
|
||||
_, p := q.ans5, q.para5
|
||||
fmt.Printf("【input】:%v 【output】:%v\n", p, longestPalindrome(p.s))
|
||||
}
|
||||
fmt.Printf("\n\n\n")
|
||||
}
|
186
leetcode/0005.Longest-Palindromic-Substring/README.md
Normal file
186
leetcode/0005.Longest-Palindromic-Substring/README.md
Normal file
@ -0,0 +1,186 @@
|
||||
# [5. Longest Palindromic Substring](https://leetcode.com/problems/longest-palindromic-substring/)
|
||||
|
||||
|
||||
## 题目
|
||||
|
||||
Given a string `s`, return *the longest palindromic substring* in `s`.
|
||||
|
||||
**Example 1:**
|
||||
|
||||
```
|
||||
Input: s = "babad"
|
||||
Output: "bab"
|
||||
Note: "aba" is also a valid answer.
|
||||
|
||||
```
|
||||
|
||||
**Example 2:**
|
||||
|
||||
```
|
||||
Input: s = "cbbd"
|
||||
Output: "bb"
|
||||
|
||||
```
|
||||
|
||||
**Example 3:**
|
||||
|
||||
```
|
||||
Input: s = "a"
|
||||
Output: "a"
|
||||
|
||||
```
|
||||
|
||||
**Example 4:**
|
||||
|
||||
```
|
||||
Input: s = "ac"
|
||||
Output: "a"
|
||||
|
||||
```
|
||||
|
||||
**Constraints:**
|
||||
|
||||
- `1 <= s.length <= 1000`
|
||||
- `s` consist of only digits and English letters (lower-case and/or upper-case),
|
||||
|
||||
## 题目大意
|
||||
|
||||
给你一个字符串 `s`,找到 `s` 中最长的回文子串。
|
||||
|
||||
## 解题思路
|
||||
|
||||
- 此题非常经典,并且有多种解法。
|
||||
- 解法一,动态规划。定义 `dp[i][j]` 表示从字符串第 `i` 个字符到第 `j` 个字符这一段子串是否是回文串。由回文串的性质可以得知,回文串去掉一头一尾相同的字符以后,剩下的还是回文串。所以状态转移方程是 `dp[i][j] = (s[i] == s[j]) && ((j-i < 3) || dp[i+1][j-1])`,注意特殊的情况,`j - i == 1` 的时候,即只有 2 个字符的情况,只需要判断这 2 个字符是否相同即可。`j - i == 2` 的时候,即只有 3 个字符的情况,只需要判断除去中心以外对称的 2 个字符是否相等。每次循环动态维护保存最长回文串即可。时间复杂度 O(n^2),空间复杂度 O(n^2)。
|
||||
- 解法二,中心扩散法。动态规划的方法中,我们将任意起始,终止范围内的字符串都判断了一遍。其实没有这个必要,如果不是最长回文串,无需判断并保存结果。所以动态规划的方法在空间复杂度上还有优化空间。判断回文有一个核心问题是找到“轴心”。如果长度是偶数,那么轴心是中心虚拟的,如果长度是奇数,那么轴心正好是正中心的那个字母。中心扩散法的思想是枚举每个轴心的位置。然后做两次假设,假设最长回文串是偶数,那么以虚拟中心往 2 边扩散;假设最长回文串是奇数,那么以正中心的字符往 2 边扩散。扩散的过程就是对称判断两边字符是否相等的过程。这个方法时间复杂度和动态规划是一样的,但是空间复杂度降低了。时间复杂度 O(n^2),空间复杂度 O(1)。
|
||||
- 解法三,滑动窗口。这个写法其实就是中心扩散法变了一个写法。中心扩散是依次枚举每一个轴心。滑动窗口的方法稍微优化了一点,有些轴心两边字符不相等,下次就不会枚举这些不可能形成回文子串的轴心了。不过这点优化并没有优化时间复杂度,时间复杂度 O(n^2),空间复杂度 O(1)。
|
||||
- 解法四,马拉车算法。这个算法是本题的最优解,也是最复杂的解法。时间复杂度 O(n),空间复杂度 O(n)。中心扩散法有 2 处有重复判断,第一处是每次都往两边扩散,不同中心扩散多次,实际上有很多重复判断的字符,能否不重复判断?第二处,中心能否跳跃选择,不是每次都枚举,是否可以利用前一次的信息,跳跃选择下一次的中心?马拉车算法针对重复判断的问题做了优化,增加了一个辅助数组,将时间复杂度从 O(n^2) 优化到了 O(n),空间换了时间,空间复杂度增加到 O(n)。
|
||||
|
||||

|
||||
|
||||
- 首先是预处理,向字符串的头尾以及每两个字符中间添加一个特殊字符 `#`,比如字符串 `aaba` 处理后会变成 `#a#a#b#a#`。那么原先长度为偶数的回文字符串 `aa` 会变成长度为奇数的回文字符串 `#a#a#`,而长度为奇数的回文字符串 `aba` 会变成长度仍然为奇数的回文字符串 `#a#b#a#`,经过预处理以后,都会变成长度为奇数的字符串。**注意这里的特殊字符不需要是没有出现过的字母,也可以使用任何一个字符来作为这个特殊字符。**这是因为,当我们只考虑长度为奇数的回文字符串时,每次我们比较的两个字符奇偶性一定是相同的,所以原来字符串中的字符不会与插入的特殊字符互相比较,不会因此产生问题。**预处理以后,以某个中心扩散的步数和实际字符串长度是相等的。**因为半径里面包含了插入的特殊字符,又由于左右对称的性质,所以扩散半径就等于原来回文子串的长度。
|
||||
|
||||

|
||||
|
||||
- 核心部分是如何通过左边已经扫描过的数据推出右边下一次要扩散的中心。这里定义下一次要扩散的中心下标是 `i`。如果 `i` 比 `maxRight` 要小,只能继续中心扩散。如果 `i` 比 `maxRight` 大,这是又分为 3 种情况。三种情况见上图。将上述 3 种情况总结起来,就是 :`dp[i] = min(maxRight-i, dp[2*center-i])`,其中,`mirror` 相对于 `center` 是和 `i` 中心对称的,所以它的下标可以计算出来是 `2*center-i`。更新完 `dp[i]` 以后,就要进行中心扩散了。中心扩散以后动态维护最长回文串并相应的更新 `center`,`maxRight`,并且记录下原始字符串的起始位置 `begin` 和 `maxLen`。
|
||||
|
||||
## 代码
|
||||
|
||||
```go
|
||||
package leetcode
|
||||
|
||||
// 解法一 Manacher's algorithm,时间复杂度 O(n),空间复杂度 O(n)
|
||||
func longestPalindrome(s string) string {
|
||||
if len(s) < 2 {
|
||||
return s
|
||||
}
|
||||
newS := make([]rune, 0)
|
||||
newS = append(newS, '#')
|
||||
for _, c := range s {
|
||||
newS = append(newS, c)
|
||||
newS = append(newS, '#')
|
||||
}
|
||||
// dp[i]: 以预处理字符串下标 i 为中心的回文半径(奇数长度时不包括中心)
|
||||
// maxRight: 通过中心扩散的方式能够扩散的最右边的下标
|
||||
// center: 与 maxRight 对应的中心字符的下标
|
||||
// maxLen: 记录最长回文串的半径
|
||||
// begin: 记录最长回文串在起始串 s 中的起始下标
|
||||
dp, maxRight, center, maxLen, begin := make([]int, len(newS)), 0, 0, 1, 0
|
||||
for i := 0; i < len(newS); i++ {
|
||||
if i < maxRight {
|
||||
// 这一行代码是 Manacher 算法的关键所在
|
||||
dp[i] = min(maxRight-i, dp[2*center-i])
|
||||
}
|
||||
// 中心扩散法更新 dp[i]
|
||||
left, right := i-(1+dp[i]), i+(1+dp[i])
|
||||
for left >= 0 && right < len(newS) && newS[left] == newS[right] {
|
||||
dp[i]++
|
||||
left--
|
||||
right++
|
||||
}
|
||||
// 更新 maxRight,它是遍历过的 i 的 i + dp[i] 的最大者
|
||||
if i+dp[i] > maxRight {
|
||||
maxRight = i + dp[i]
|
||||
center = i
|
||||
}
|
||||
// 记录最长回文子串的长度和相应它在原始字符串中的起点
|
||||
if dp[i] > maxLen {
|
||||
maxLen = dp[i]
|
||||
begin = (i - maxLen) / 2 // 这里要除以 2 因为有我们插入的辅助字符 #
|
||||
}
|
||||
}
|
||||
return s[begin : begin+maxLen]
|
||||
}
|
||||
|
||||
func min(x, y int) int {
|
||||
if x < y {
|
||||
return x
|
||||
}
|
||||
return y
|
||||
}
|
||||
|
||||
// 解法二 滑动窗口,时间复杂度 O(n^2),空间复杂度 O(1)
|
||||
func longestPalindrome1(s string) string {
|
||||
if len(s) == 0 {
|
||||
return ""
|
||||
}
|
||||
left, right, pl, pr := 0, -1, 0, 0
|
||||
for left < len(s) {
|
||||
// 移动到相同字母的最右边(如果有相同字母)
|
||||
for right+1 < len(s) && s[left] == s[right+1] {
|
||||
right++
|
||||
}
|
||||
// 找到回文的边界
|
||||
for left-1 >= 0 && right+1 < len(s) && s[left-1] == s[right+1] {
|
||||
left--
|
||||
right++
|
||||
}
|
||||
if right-left > pr-pl {
|
||||
pl, pr = left, right
|
||||
}
|
||||
// 重置到下一次寻找回文的中心
|
||||
left = (left+right)/2 + 1
|
||||
right = left
|
||||
}
|
||||
return s[pl : pr+1]
|
||||
}
|
||||
|
||||
// 解法三 中心扩散法,时间复杂度 O(n^2),空间复杂度 O(1)
|
||||
func longestPalindrome2(s string) string {
|
||||
res := ""
|
||||
for i := 0; i < len(s); i++ {
|
||||
res = maxPalindrome(s, i, i, res)
|
||||
res = maxPalindrome(s, i, i+1, res)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func maxPalindrome(s string, i, j int, res string) string {
|
||||
sub := ""
|
||||
for i >= 0 && j < len(s) && s[i] == s[j] {
|
||||
sub = s[i : j+1]
|
||||
i--
|
||||
j++
|
||||
}
|
||||
if len(res) < len(sub) {
|
||||
return sub
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
// 解法四 DP,时间复杂度 O(n^2),空间复杂度 O(n^2)
|
||||
func longestPalindrome3(s string) string {
|
||||
res, dp := "", make([][]bool, len(s))
|
||||
for i := 0; i < len(s); i++ {
|
||||
dp[i] = make([]bool, len(s))
|
||||
}
|
||||
for i := len(s) - 1; i >= 0; i-- {
|
||||
for j := i; j < len(s); j++ {
|
||||
dp[i][j] = (s[i] == s[j]) && ((j-i < 3) || dp[i+1][j-1])
|
||||
if dp[i][j] && (res == "" || j-i+1 > len(res)) {
|
||||
res = s[i : j+1]
|
||||
}
|
||||
}
|
||||
}
|
||||
return res
|
||||
}
|
||||
```
|
26
leetcode/0006.ZigZag-Conversion/6. ZigZag Conversion.go
Normal file
26
leetcode/0006.ZigZag-Conversion/6. ZigZag Conversion.go
Normal file
@ -0,0 +1,26 @@
|
||||
package leetcode
|
||||
|
||||
func convert(s string, numRows int) string {
|
||||
matrix, down, up := make([][]byte, numRows, numRows), 0, numRows-2
|
||||
for i := 0; i != len(s); {
|
||||
if down != numRows {
|
||||
matrix[down] = append(matrix[down], byte(s[i]))
|
||||
down++
|
||||
i++
|
||||
} else if up > 0 {
|
||||
matrix[up] = append(matrix[up], byte(s[i]))
|
||||
up--
|
||||
i++
|
||||
} else {
|
||||
up = numRows - 2
|
||||
down = 0
|
||||
}
|
||||
}
|
||||
solution := make([]byte, 0, len(s))
|
||||
for _, row := range matrix {
|
||||
for _, item := range row {
|
||||
solution = append(solution, item)
|
||||
}
|
||||
}
|
||||
return string(solution)
|
||||
}
|
53
leetcode/0006.ZigZag-Conversion/6. ZigZag Conversion_test.go
Normal file
53
leetcode/0006.ZigZag-Conversion/6. ZigZag Conversion_test.go
Normal file
@ -0,0 +1,53 @@
|
||||
package leetcode
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type question6 struct {
|
||||
para6
|
||||
ans6
|
||||
}
|
||||
|
||||
// para 是参数
|
||||
// one 代表第一个参数
|
||||
type para6 struct {
|
||||
s string
|
||||
numRows int
|
||||
}
|
||||
|
||||
// ans 是答案
|
||||
// one 代表第一个答案
|
||||
type ans6 struct {
|
||||
one string
|
||||
}
|
||||
|
||||
func Test_Problem6(t *testing.T) {
|
||||
|
||||
qs := []question6{
|
||||
|
||||
{
|
||||
para6{"PAYPALISHIRING", 3},
|
||||
ans6{"PAHNAPLSIIGYIR"},
|
||||
},
|
||||
|
||||
{
|
||||
para6{"PAYPALISHIRING", 4},
|
||||
ans6{"PINALSIGYAHRPI"},
|
||||
},
|
||||
|
||||
{
|
||||
para6{"A", 1},
|
||||
ans6{"A"},
|
||||
},
|
||||
}
|
||||
|
||||
fmt.Printf("------------------------Leetcode Problem 6------------------------\n")
|
||||
|
||||
for _, q := range qs {
|
||||
_, p := q.ans6, q.para6
|
||||
fmt.Printf("【input】:%v 【output】:%v\n", p, convert(p.s, p.numRows))
|
||||
}
|
||||
fmt.Printf("\n\n\n")
|
||||
}
|
107
leetcode/0006.ZigZag-Conversion/README.md
Normal file
107
leetcode/0006.ZigZag-Conversion/README.md
Normal file
@ -0,0 +1,107 @@
|
||||
# [6. ZigZag Conversion](https://leetcode.com/problems/zigzag-conversion/)
|
||||
|
||||
|
||||
## 题目
|
||||
|
||||
The string `"PAYPALISHIRING"` is written in a zigzag pattern on a given number of rows like this: (you may want to display this pattern in a fixed font for better legibility)
|
||||
|
||||
```
|
||||
P A H N
|
||||
A P L S I I G
|
||||
Y I R
|
||||
```
|
||||
|
||||
And then read line by line: `"PAHNAPLSIIGYIR"`
|
||||
|
||||
Write the code that will take a string and make this conversion given a number of rows:
|
||||
|
||||
```
|
||||
string convert(string s, int numRows);
|
||||
```
|
||||
|
||||
**Example 1:**
|
||||
|
||||
```
|
||||
Input: s = "PAYPALISHIRING", numRows = 3
|
||||
Output: "PAHNAPLSIIGYIR"
|
||||
```
|
||||
|
||||
**Example 2:**
|
||||
|
||||
```
|
||||
Input: s = "PAYPALISHIRING", numRows = 4
|
||||
Output: "PINALSIGYAHRPI"
|
||||
Explanation:
|
||||
P I N
|
||||
A L S I G
|
||||
Y A H R
|
||||
P I
|
||||
```
|
||||
|
||||
**Example 3:**
|
||||
|
||||
```
|
||||
Input: s = "A", numRows = 1
|
||||
Output: "A"
|
||||
```
|
||||
|
||||
**Constraints:**
|
||||
|
||||
- `1 <= s.length <= 1000`
|
||||
- `s` consists of English letters (lower-case and upper-case), `','` and `'.'`.
|
||||
- `1 <= numRows <= 1000`
|
||||
|
||||
## 题目大意
|
||||
|
||||
将一个给定字符串 `s` 根据给定的行数 `numRows` ,以从上往下、从左到右进行 Z 字形排列。
|
||||
|
||||
比如输入字符串为 `"PAYPALISHIRING"` 行数为 3 时,排列如下:
|
||||
|
||||
```go
|
||||
P A H N
|
||||
A P L S I I G
|
||||
Y I R
|
||||
```
|
||||
|
||||
之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:`"PAHNAPLSIIGYIR"`。
|
||||
|
||||
请你实现这个将字符串进行指定行数变换的函数:
|
||||
|
||||
```go
|
||||
string convert(string s, int numRows);
|
||||
```
|
||||
|
||||
## 解题思路
|
||||
|
||||
- 这一题没有什么算法思想,考察的是对程序控制的能力。用 2 个变量保存方向,当垂直输出的行数达到了规定的目标行数以后,需要从下往上转折到第一行,循环中控制好方向ji
|
||||
|
||||
## 代码
|
||||
|
||||
```go
|
||||
package leetcode
|
||||
|
||||
func convert(s string, numRows int) string {
|
||||
matrix, down, up := make([][]byte, numRows, numRows), 0, numRows-2
|
||||
for i := 0; i != len(s); {
|
||||
if down != numRows {
|
||||
matrix[down] = append(matrix[down], byte(s[i]))
|
||||
down++
|
||||
i++
|
||||
} else if up > 0 {
|
||||
matrix[up] = append(matrix[up], byte(s[i]))
|
||||
up--
|
||||
i++
|
||||
} else {
|
||||
up = numRows - 2
|
||||
down = 0
|
||||
}
|
||||
}
|
||||
solution := make([]byte, 0, len(s))
|
||||
for _, row := range matrix {
|
||||
for _, item := range row {
|
||||
solution = append(solution, item)
|
||||
}
|
||||
}
|
||||
return string(solution)
|
||||
}
|
||||
```
|
@ -26,22 +26,22 @@ func Test_Problem7(t *testing.T) {
|
||||
|
||||
qs := []question7{
|
||||
|
||||
question7{
|
||||
{
|
||||
para7{321},
|
||||
ans7{123},
|
||||
},
|
||||
|
||||
question7{
|
||||
{
|
||||
para7{-123},
|
||||
ans7{-321},
|
||||
},
|
||||
|
||||
question7{
|
||||
{
|
||||
para7{120},
|
||||
ans7{21},
|
||||
},
|
||||
|
||||
question7{
|
||||
{
|
||||
para7{1534236469},
|
||||
ans7{0},
|
||||
},
|
||||
|
@ -0,0 +1,56 @@
|
||||
package leetcode
|
||||
|
||||
func myAtoi(s string) int {
|
||||
maxInt, signAllowed, whitespaceAllowed, sign, digits := int64(2<<30), true, true, 1, []int{}
|
||||
for _, c := range s {
|
||||
if c == ' ' && whitespaceAllowed {
|
||||
continue
|
||||
}
|
||||
if signAllowed {
|
||||
if c == '+' {
|
||||
signAllowed = false
|
||||
whitespaceAllowed = false
|
||||
continue
|
||||
} else if c == '-' {
|
||||
sign = -1
|
||||
signAllowed = false
|
||||
whitespaceAllowed = false
|
||||
continue
|
||||
}
|
||||
}
|
||||
if c < '0' || c > '9' {
|
||||
break
|
||||
}
|
||||
whitespaceAllowed, signAllowed = false, false
|
||||
digits = append(digits, int(c-48))
|
||||
}
|
||||
var num, place int64
|
||||
place, num = 1, 0
|
||||
lastLeading0Index := -1
|
||||
for i, d := range digits {
|
||||
if d == 0 {
|
||||
lastLeading0Index = i
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
if lastLeading0Index > -1 {
|
||||
digits = digits[lastLeading0Index+1:]
|
||||
}
|
||||
var rtnMax int64
|
||||
if sign > 0 {
|
||||
rtnMax = maxInt - 1
|
||||
} else {
|
||||
rtnMax = maxInt
|
||||
}
|
||||
digitsCount := len(digits)
|
||||
for i := digitsCount - 1; i >= 0; i-- {
|
||||
num += int64(digits[i]) * place
|
||||
place *= 10
|
||||
if digitsCount-i > 10 || num > rtnMax {
|
||||
return int(int64(sign) * rtnMax)
|
||||
}
|
||||
}
|
||||
num *= int64(sign)
|
||||
return int(num)
|
||||
}
|
@ -0,0 +1,62 @@
|
||||
package leetcode
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type question8 struct {
|
||||
para8
|
||||
ans8
|
||||
}
|
||||
|
||||
// para 是参数
|
||||
// one 代表第一个参数
|
||||
type para8 struct {
|
||||
one string
|
||||
}
|
||||
|
||||
// ans 是答案
|
||||
// one 代表第一个答案
|
||||
type ans8 struct {
|
||||
one int
|
||||
}
|
||||
|
||||
func Test_Problem8(t *testing.T) {
|
||||
|
||||
qs := []question8{
|
||||
|
||||
{
|
||||
para8{"42"},
|
||||
ans8{42},
|
||||
},
|
||||
|
||||
{
|
||||
para8{" -42"},
|
||||
ans8{-42},
|
||||
},
|
||||
|
||||
{
|
||||
para8{"4193 with words"},
|
||||
ans8{4193},
|
||||
},
|
||||
|
||||
{
|
||||
para8{"words and 987"},
|
||||
ans8{0},
|
||||
},
|
||||
|
||||
{
|
||||
para8{"-91283472332"},
|
||||
ans8{-2147483648},
|
||||
},
|
||||
}
|
||||
|
||||
fmt.Printf("------------------------Leetcode Problem 8------------------------\n")
|
||||
|
||||
for _, q := range qs {
|
||||
_, p := q.ans8, q.para8
|
||||
fmt.Printf("【input】:%v 【output】:%v\n", p.one, myAtoi(p.one))
|
||||
}
|
||||
fmt.Printf("\n\n\n")
|
||||
}
|
192
leetcode/0008.String-to-Integer-atoi/README.md
Normal file
192
leetcode/0008.String-to-Integer-atoi/README.md
Normal file
@ -0,0 +1,192 @@
|
||||
# [8. String to Integer (atoi)](https://leetcode.com/problems/string-to-integer-atoi/)
|
||||
|
||||
|
||||
## 题目
|
||||
|
||||
Implement the `myAtoi(string s)` function, which converts a string to a 32-bit signed integer (similar to C/C++'s `atoi` function).
|
||||
|
||||
The algorithm for `myAtoi(string s)` is as follows:
|
||||
|
||||
1. Read in and ignore any leading whitespace.
|
||||
2. Check if the next character (if not already at the end of the string) is `'-'` or `'+'`. Read this character in if it is either. This determines if the final result is negative or positive respectively. Assume the result is positive if neither is present.
|
||||
3. Read in next the characters until the next non-digit charcter or the end of the input is reached. The rest of the string is ignored.
|
||||
4. Convert these digits into an integer (i.e. `"123" -> 123`, `"0032" -> 32`). If no digits were read, then the integer is `0`. Change the sign as necessary (from step 2).
|
||||
5. If the integer is out of the 32-bit signed integer range `[-231, 231 - 1]`, then clamp the integer so that it remains in the range. Specifically, integers less than `231` should be clamped to `231`, and integers greater than `231 - 1` should be clamped to `231 - 1`.
|
||||
6. Return the integer as the final result.
|
||||
|
||||
**Note:**
|
||||
|
||||
- Only the space character `' '` is considered a whitespace character.
|
||||
- **Do not ignore** any characters other than the leading whitespace or the rest of the string after the digits.
|
||||
|
||||
**Example 1:**
|
||||
|
||||
```
|
||||
Input: s = "42"
|
||||
Output: 42
|
||||
Explanation: The underlined characters are what is read in, the caret is the current reader position.
|
||||
Step 1: "42" (no characters read because there is no leading whitespace)
|
||||
^
|
||||
Step 2: "42" (no characters read because there is neither a '-' nor '+')
|
||||
^
|
||||
Step 3: "42" ("42" is read in)
|
||||
^
|
||||
The parsed integer is 42.
|
||||
Since 42 is in the range [-231, 231 - 1], the final result is 42.
|
||||
|
||||
```
|
||||
|
||||
**Example 2:**
|
||||
|
||||
```
|
||||
Input: s = " -42"
|
||||
Output: -42
|
||||
Explanation:
|
||||
Step 1: " -42" (leading whitespace is read and ignored)
|
||||
^
|
||||
Step 2: " -42" ('-' is read, so the result should be negative)
|
||||
^
|
||||
Step 3: " -42" ("42" is read in)
|
||||
^
|
||||
The parsed integer is -42.
|
||||
Since -42 is in the range [-231, 231 - 1], the final result is -42.
|
||||
|
||||
```
|
||||
|
||||
**Example 3:**
|
||||
|
||||
```
|
||||
Input: s = "4193 with words"
|
||||
Output: 4193
|
||||
Explanation:
|
||||
Step 1: "4193 with words" (no characters read because there is no leading whitespace)
|
||||
^
|
||||
Step 2: "4193 with words" (no characters read because there is neither a '-' nor '+')
|
||||
^
|
||||
Step 3: "4193 with words" ("4193" is read in; reading stops because the next character is a non-digit)
|
||||
^
|
||||
The parsed integer is 4193.
|
||||
Since 4193 is in the range [-231, 231 - 1], the final result is 4193.
|
||||
|
||||
```
|
||||
|
||||
**Example 4:**
|
||||
|
||||
```
|
||||
Input: s = "words and 987"
|
||||
Output: 0
|
||||
Explanation:
|
||||
Step 1: "words and 987" (no characters read because there is no leading whitespace)
|
||||
^
|
||||
Step 2: "words and 987" (no characters read because there is neither a '-' nor '+')
|
||||
^
|
||||
Step 3: "words and 987" (reading stops immediately because there is a non-digit 'w')
|
||||
^
|
||||
The parsed integer is 0 because no digits were read.
|
||||
Since 0 is in the range [-231, 231 - 1], the final result is 0.
|
||||
|
||||
```
|
||||
|
||||
**Example 5:**
|
||||
|
||||
```
|
||||
Input: s = "-91283472332"
|
||||
Output: -2147483648
|
||||
Explanation:
|
||||
Step 1: "-91283472332" (no characters read because there is no leading whitespace)
|
||||
^
|
||||
Step 2: "-91283472332" ('-' is read, so the result should be negative)
|
||||
^
|
||||
Step 3: "-91283472332" ("91283472332" is read in)
|
||||
^
|
||||
The parsed integer is -91283472332.
|
||||
Since -91283472332 is less than the lower bound of the range [-231, 231 - 1], the final result is clamped to -231 = -2147483648.
|
||||
```
|
||||
|
||||
**Constraints:**
|
||||
|
||||
- `0 <= s.length <= 200`
|
||||
- `s` consists of English letters (lower-case and upper-case), digits (`0-9`), `' '`, `'+'`
|
||||
|
||||
## 题目大意
|
||||
|
||||
请你来实现一个 myAtoi(string s) 函数,使其能将字符串转换成一个 32 位有符号整数(类似 C/C++ 中的 atoi 函数)。
|
||||
|
||||
函数 myAtoi(string s) 的算法如下:
|
||||
|
||||
- 读入字符串并丢弃无用的前导空格
|
||||
- 检查下一个字符(假设还未到字符末尾)为正还是负号,读取该字符(如果有)。 确定最终结果是负数还是正数。 如果两者都不存在,则假定结果为正。
|
||||
- 读入下一个字符,直到到达下一个非数字字符或到达输入的结尾。字符串的其余部分将被忽略。
|
||||
- 将前面步骤读入的这些数字转换为整数(即,"123" -> 123, "0032" -> 32)。如果没有读入数字,则整数为 0 。必要时更改符号(从步骤 2 开始)。
|
||||
- 如果整数数超过 32 位有符号整数范围 [−231, 231 − 1] ,需要截断这个整数,使其保持在这个范围内。具体来说,小于 −231 的整数应该被固定为 −231 ,大于 231 − 1 的整数应该被固定为 231 − 1 。
|
||||
- 返回整数作为最终结果。
|
||||
|
||||
注意:
|
||||
|
||||
- 本题中的空白字符只包括空格字符 ' ' 。
|
||||
- 除前导空格或数字后的其余字符串外,请勿忽略 任何其他字符。
|
||||
|
||||
## 解题思路
|
||||
|
||||
- 这题是简单题。题目要求实现类似 `C++` 中 `atoi` 函数的功能。这个函数功能是将字符串类型的数字转成 `int` 类型数字。先去除字符串中的前导空格,并判断记录数字的符号。数字需要去掉前导 `0` 。最后将数字转换成数字类型,判断是否超过 `int` 类型的上限 `[-2^31, 2^31 - 1]`,如果超过上限,需要输出边界,即 `-2^31`,或者 `2^31 - 1`。
|
||||
|
||||
## 代码
|
||||
|
||||
```go
|
||||
package leetcode
|
||||
|
||||
func myAtoi(s string) int {
|
||||
maxInt, signAllowed, whitespaceAllowed, sign, digits := int64(2<<30), true, true, 1, []int{}
|
||||
for _, c := range s {
|
||||
if c == ' ' && whitespaceAllowed {
|
||||
continue
|
||||
}
|
||||
if signAllowed {
|
||||
if c == '+' {
|
||||
signAllowed = false
|
||||
whitespaceAllowed = false
|
||||
continue
|
||||
} else if c == '-' {
|
||||
sign = -1
|
||||
signAllowed = false
|
||||
whitespaceAllowed = false
|
||||
continue
|
||||
}
|
||||
}
|
||||
if c < '0' || c > '9' {
|
||||
break
|
||||
}
|
||||
whitespaceAllowed, signAllowed = false, false
|
||||
digits = append(digits, int(c-48))
|
||||
}
|
||||
var num, place int64
|
||||
place, num = 1, 0
|
||||
lastLeading0Index := -1
|
||||
for i, d := range digits {
|
||||
if d == 0 {
|
||||
lastLeading0Index = i
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
if lastLeading0Index > -1 {
|
||||
digits = digits[lastLeading0Index+1:]
|
||||
}
|
||||
var rtnMax int64
|
||||
if sign > 0 {
|
||||
rtnMax = maxInt - 1
|
||||
} else {
|
||||
rtnMax = maxInt
|
||||
}
|
||||
digitsCount := len(digits)
|
||||
for i := digitsCount - 1; i >= 0; i-- {
|
||||
num += int64(digits[i]) * place
|
||||
place *= 10
|
||||
if digitsCount-i > 10 || num > rtnMax {
|
||||
return int(int64(sign) * rtnMax)
|
||||
}
|
||||
}
|
||||
num *= int64(sign)
|
||||
return int(num)
|
||||
}
|
||||
```
|
@ -2,7 +2,33 @@ package leetcode
|
||||
|
||||
import "strconv"
|
||||
|
||||
// 解法一
|
||||
func isPalindrome(x int) bool {
|
||||
if x < 0 {
|
||||
return false
|
||||
}
|
||||
if x == 0 {
|
||||
return true
|
||||
}
|
||||
if x%10 == 0 {
|
||||
return false
|
||||
}
|
||||
arr := make([]int, 0, 32)
|
||||
for x > 0 {
|
||||
arr = append(arr, x%10)
|
||||
x = x / 10
|
||||
}
|
||||
sz := len(arr)
|
||||
for i, j := 0, sz-1; i <= j; i, j = i+1, j-1 {
|
||||
if arr[i] != arr[j] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// 解法二 数字转字符串
|
||||
func isPalindrome1(x int) bool {
|
||||
if x < 0 {
|
||||
return false
|
||||
}
|
||||
|
@ -26,37 +26,37 @@ func Test_Problem9(t *testing.T) {
|
||||
|
||||
qs := []question9{
|
||||
|
||||
question9{
|
||||
{
|
||||
para9{121},
|
||||
ans9{true},
|
||||
},
|
||||
|
||||
question9{
|
||||
{
|
||||
para9{-121},
|
||||
ans9{false},
|
||||
},
|
||||
|
||||
question9{
|
||||
{
|
||||
para9{10},
|
||||
ans9{false},
|
||||
},
|
||||
|
||||
question9{
|
||||
{
|
||||
para9{321},
|
||||
ans9{false},
|
||||
},
|
||||
|
||||
question9{
|
||||
{
|
||||
para9{-123},
|
||||
ans9{false},
|
||||
},
|
||||
|
||||
question9{
|
||||
{
|
||||
para9{120},
|
||||
ans9{false},
|
||||
},
|
||||
|
||||
question9{
|
||||
{
|
||||
para9{1534236469},
|
||||
ans9{false},
|
||||
},
|
||||
|
@ -49,7 +49,33 @@ package leetcode
|
||||
|
||||
import "strconv"
|
||||
|
||||
// 解法一
|
||||
func isPalindrome(x int) bool {
|
||||
if x < 0 {
|
||||
return false
|
||||
}
|
||||
if x == 0 {
|
||||
return true
|
||||
}
|
||||
if x%10 == 0 {
|
||||
return false
|
||||
}
|
||||
arr := make([]int, 0, 32)
|
||||
for x > 0 {
|
||||
arr = append(arr, x%10)
|
||||
x = x / 10
|
||||
}
|
||||
sz := len(arr)
|
||||
for i, j := 0, sz-1; i <= j; i, j = i+1, j-1 {
|
||||
if arr[i] != arr[j] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// 解法二 数字转字符串
|
||||
func isPalindrome1(x int) bool {
|
||||
if x < 0 {
|
||||
return false
|
||||
}
|
||||
@ -66,4 +92,5 @@ func isPalindrome(x int) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
```
|
@ -26,12 +26,12 @@ func Test_Problem11(t *testing.T) {
|
||||
|
||||
qs := []question11{
|
||||
|
||||
question11{
|
||||
{
|
||||
para11{[]int{1, 8, 6, 2, 5, 4, 8, 3, 7}},
|
||||
ans11{49},
|
||||
},
|
||||
|
||||
question11{
|
||||
{
|
||||
para11{[]int{1, 1}},
|
||||
ans11{1},
|
||||
},
|
||||
|
15
leetcode/0012.Integer-to-Roman/12. Integer to Roman.go
Normal file
15
leetcode/0012.Integer-to-Roman/12. Integer to Roman.go
Normal file
@ -0,0 +1,15 @@
|
||||
package leetcode
|
||||
|
||||
func intToRoman(num int) string {
|
||||
values := []int{1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1}
|
||||
symbols := []string{"M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"}
|
||||
res, i := "", 0
|
||||
for num != 0 {
|
||||
for values[i] > num {
|
||||
i++
|
||||
}
|
||||
num -= values[i]
|
||||
res += symbols[i]
|
||||
}
|
||||
return res
|
||||
}
|
71
leetcode/0012.Integer-to-Roman/12. Integer to Roman_test.go
Normal file
71
leetcode/0012.Integer-to-Roman/12. Integer to Roman_test.go
Normal file
@ -0,0 +1,71 @@
|
||||
package leetcode
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type question12 struct {
|
||||
para12
|
||||
ans12
|
||||
}
|
||||
|
||||
// para 是参数
|
||||
// one 代表第一个参数
|
||||
type para12 struct {
|
||||
one int
|
||||
}
|
||||
|
||||
// ans 是答案
|
||||
// one 代表第一个答案
|
||||
type ans12 struct {
|
||||
one string
|
||||
}
|
||||
|
||||
func Test_Problem12(t *testing.T) {
|
||||
|
||||
qs := []question12{
|
||||
|
||||
{
|
||||
para12{3},
|
||||
ans12{"III"},
|
||||
},
|
||||
|
||||
{
|
||||
para12{4},
|
||||
ans12{"IV"},
|
||||
},
|
||||
|
||||
{
|
||||
para12{9},
|
||||
ans12{"IX"},
|
||||
},
|
||||
|
||||
{
|
||||
para12{58},
|
||||
ans12{"LVIII"},
|
||||
},
|
||||
|
||||
{
|
||||
para12{1994},
|
||||
ans12{"MCMXCIV"},
|
||||
},
|
||||
{
|
||||
para12{123},
|
||||
ans12{"CXXIII"},
|
||||
},
|
||||
|
||||
{
|
||||
para12{120},
|
||||
ans12{"CXX"},
|
||||
},
|
||||
}
|
||||
|
||||
fmt.Printf("------------------------Leetcode Problem 12------------------------\n")
|
||||
|
||||
for _, q := range qs {
|
||||
_, p := q.ans12, q.para12
|
||||
fmt.Printf("【input】:%v 【output】:%v\n", p.one, intToRoman(p.one))
|
||||
}
|
||||
fmt.Printf("\n\n\n")
|
||||
}
|
102
leetcode/0012.Integer-to-Roman/README.md
Normal file
102
leetcode/0012.Integer-to-Roman/README.md
Normal file
@ -0,0 +1,102 @@
|
||||
# [12. Integer to Roman](https://leetcode.com/problems/integer-to-roman/)
|
||||
|
||||
|
||||
## 题目
|
||||
|
||||
Roman numerals are represented by seven different symbols: `I`, `V`, `X`, `L`, `C`, `D` and `M`.
|
||||
|
||||
```
|
||||
Symbol Value
|
||||
I 1
|
||||
V 5
|
||||
X 10
|
||||
L 50
|
||||
C 100
|
||||
D 500
|
||||
M 1000
|
||||
```
|
||||
|
||||
For example, `2` is written as `II` in Roman numeral, just two one's added together. `12` is written as `XII`, which is simply `X + II`. The number `27` is written as `XXVII`, which is `XX + V + II`.
|
||||
|
||||
Roman numerals are usually written largest to smallest from left to right. However, the numeral for four is not `IIII`. Instead, the number four is written as `IV`. Because the one is before the five we subtract it making four. The same principle applies to the number nine, which is written as `IX`. There are six instances where subtraction is used:
|
||||
|
||||
- `I` can be placed before `V` (5) and `X` (10) to make 4 and 9.
|
||||
- `X` can be placed before `L` (50) and `C` (100) to make 40 and 90.
|
||||
- `C` can be placed before `D` (500) and `M` (1000) to make 400 and 900.
|
||||
|
||||
Given an integer, convert it to a roman numeral.
|
||||
|
||||
**Example 1:**
|
||||
|
||||
```
|
||||
Input: num = 3
|
||||
Output: "III"
|
||||
```
|
||||
|
||||
**Example 2:**
|
||||
|
||||
```
|
||||
Input: num = 4
|
||||
Output: "IV"
|
||||
```
|
||||
|
||||
**Example 3:**
|
||||
|
||||
```
|
||||
Input: num = 9
|
||||
Output: "IX"
|
||||
```
|
||||
|
||||
**Example 4:**
|
||||
|
||||
```
|
||||
Input: num = 58
|
||||
Output: "LVIII"
|
||||
Explanation: L = 50, V = 5, III = 3.
|
||||
```
|
||||
|
||||
**Example 5:**
|
||||
|
||||
```
|
||||
Input: num = 1994
|
||||
Output: "MCMXCIV"
|
||||
Explanation: M = 1000, CM = 900, XC = 90 and IV = 4.
|
||||
```
|
||||
|
||||
**Constraints:**
|
||||
|
||||
- `1 <= num <= 3999`
|
||||
|
||||
## 题目大意
|
||||
|
||||
通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如 4 不写做 IIII,而是 IV。数字 1 在数字 5 的左边,所表示的数等于大数 5 减小数 1 得到的数值 4 。同样地,数字 9 表示为 IX。这个特殊的规则只适用于以下六种情况:
|
||||
|
||||
- I 可以放在 V (5) 和 X (10) 的左边,来表示 4 和 9。
|
||||
- X 可以放在 L (50) 和 C (100) 的左边,来表示 40 和 90。
|
||||
- C 可以放在 D (500) 和 M (1000) 的左边,来表示 400 和 900。
|
||||
|
||||
给定一个整数,将其转为罗马数字。输入确保在 1 到 3999 的范围内。
|
||||
|
||||
## 解题思路
|
||||
|
||||
- 依照题意,优先选择大的数字,解题思路采用贪心算法。将 1-3999 范围内的罗马数字从大到小放在数组中,从头选择到尾,即可把整数转成罗马数字。
|
||||
|
||||
## 代码
|
||||
|
||||
```go
|
||||
package leetcode
|
||||
|
||||
func intToRoman(num int) string {
|
||||
values := []int{1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1}
|
||||
symbols := []string{"M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"}
|
||||
res, i := "", 0
|
||||
for num != 0 {
|
||||
for values[i] > num {
|
||||
i++
|
||||
}
|
||||
num -= values[i]
|
||||
res += symbols[i]
|
||||
}
|
||||
return res
|
||||
}
|
||||
```
|
@ -26,32 +26,32 @@ func Test_Problem13(t *testing.T) {
|
||||
|
||||
qs := []question13{
|
||||
|
||||
question13{
|
||||
{
|
||||
para13{"III"},
|
||||
ans13{3},
|
||||
},
|
||||
|
||||
question13{
|
||||
{
|
||||
para13{"IV"},
|
||||
ans13{4},
|
||||
},
|
||||
|
||||
question13{
|
||||
{
|
||||
para13{"IX"},
|
||||
ans13{9},
|
||||
},
|
||||
|
||||
question13{
|
||||
{
|
||||
para13{"LVIII"},
|
||||
ans13{58},
|
||||
},
|
||||
|
||||
question13{
|
||||
{
|
||||
para13{"MCMXCIV"},
|
||||
ans13{1994},
|
||||
},
|
||||
|
||||
question13{
|
||||
{
|
||||
para13{"MCMXICIVI"},
|
||||
ans13{2014},
|
||||
},
|
||||
|
@ -0,0 +1,16 @@
|
||||
package leetcode
|
||||
|
||||
func longestCommonPrefix(strs []string) string {
|
||||
prefix := strs[0]
|
||||
|
||||
for i := 1; i < len(strs); i++ {
|
||||
for j := 0; j < len(prefix); j++ {
|
||||
if len(strs[i]) <= j || strs[i][j] != prefix[j] {
|
||||
prefix = prefix[0:j]
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return prefix
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
package leetcode
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type question14 struct {
|
||||
para14
|
||||
ans14
|
||||
}
|
||||
|
||||
// para 是参数
|
||||
type para14 struct {
|
||||
strs []string
|
||||
}
|
||||
|
||||
// ans 是答案
|
||||
type ans14 struct {
|
||||
ans string
|
||||
}
|
||||
|
||||
func Test_Problem14(t *testing.T) {
|
||||
|
||||
qs := []question14{
|
||||
|
||||
{
|
||||
para14{[]string{"flower", "flow", "flight"}},
|
||||
ans14{"fl"},
|
||||
},
|
||||
|
||||
{
|
||||
para14{[]string{"dog", "racecar", "car"}},
|
||||
ans14{""},
|
||||
},
|
||||
|
||||
{
|
||||
para14{[]string{"ab", "a"}},
|
||||
ans14{"a"},
|
||||
},
|
||||
}
|
||||
|
||||
fmt.Printf("------------------------Leetcode Problem 14------------------------\n")
|
||||
|
||||
for _, q := range qs {
|
||||
_, p := q.ans14, q.para14
|
||||
fmt.Printf("【input】:%v 【output】:%v\n", p.strs, longestCommonPrefix(p.strs))
|
||||
}
|
||||
fmt.Printf("\n\n\n")
|
||||
}
|
57
leetcode/0014.Longest-Common-Prefix/README.md
Normal file
57
leetcode/0014.Longest-Common-Prefix/README.md
Normal file
@ -0,0 +1,57 @@
|
||||
# [14. Longest Common Prefix](https://leetcode.com/problems/longest-common-prefix/)
|
||||
|
||||
## 题目
|
||||
|
||||
Write a function to find the longest common prefix string amongst an array of strings.
|
||||
|
||||
If there is no common prefix, return an empty string "".
|
||||
|
||||
**Example 1**:
|
||||
|
||||
Input: strs = ["flower","flow","flight"]
|
||||
Output: "fl"
|
||||
|
||||
**Example 2**:
|
||||
|
||||
Input: strs = ["dog","racecar","car"]
|
||||
Output: ""
|
||||
Explanation: There is no common prefix among the input strings.
|
||||
|
||||
**Constraints:**
|
||||
|
||||
- 1 <= strs.length <= 200
|
||||
- 0 <= strs[i].length <= 200
|
||||
- strs[i] consists of only lower-case English letters.
|
||||
|
||||
## 题目大意
|
||||
|
||||
编写一个函数来查找字符串数组中的最长公共前缀。
|
||||
|
||||
如果不存在公共前缀,返回空字符串 ""。
|
||||
|
||||
## 解题思路
|
||||
|
||||
- 对 strs 按照字符串长度进行升序排序,求出 strs 中长度最小字符串的长度 minLen
|
||||
- 逐个比较长度最小字符串与其它字符串中的字符,如果不相等就返回 commonPrefix,否则就把该字符加入 commonPrefix
|
||||
|
||||
## 代码
|
||||
|
||||
```go
|
||||
|
||||
package leetcode
|
||||
|
||||
func longestCommonPrefix(strs []string) string {
|
||||
prefix := strs[0]
|
||||
|
||||
for i := 1; i < len(strs); i++ {
|
||||
for j := 0; j < len(prefix); j++ {
|
||||
if len(strs[i]) <= j || strs[i][j] != prefix[j] {
|
||||
prefix = prefix[0:j]
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return prefix
|
||||
}
|
||||
```
|
@ -4,7 +4,41 @@ import (
|
||||
"sort"
|
||||
)
|
||||
|
||||
// 解法一 最优解,双指针 + 排序
|
||||
func threeSum(nums []int) [][]int {
|
||||
sort.Ints(nums)
|
||||
result, start, end, index, addNum, length := make([][]int, 0), 0, 0, 0, 0, len(nums)
|
||||
for index = 1; index < length-1; index++ {
|
||||
start, end = 0, length-1
|
||||
if index > 1 && nums[index] == nums[index-1] {
|
||||
start = index - 1
|
||||
}
|
||||
for start < index && end > index {
|
||||
if start > 0 && nums[start] == nums[start-1] {
|
||||
start++
|
||||
continue
|
||||
}
|
||||
if end < length-1 && nums[end] == nums[end+1] {
|
||||
end--
|
||||
continue
|
||||
}
|
||||
addNum = nums[start] + nums[end] + nums[index]
|
||||
if addNum == 0 {
|
||||
result = append(result, []int{nums[start], nums[index], nums[end]})
|
||||
start++
|
||||
end--
|
||||
} else if addNum > 0 {
|
||||
end--
|
||||
} else {
|
||||
start++
|
||||
}
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// 解法二
|
||||
func threeSum1(nums []int) [][]int {
|
||||
res := [][]int{}
|
||||
counter := map[int]int{}
|
||||
for _, value := range nums {
|
||||
|
@ -26,26 +26,26 @@ func Test_Problem15(t *testing.T) {
|
||||
|
||||
qs := []question15{
|
||||
|
||||
question15{
|
||||
{
|
||||
para15{[]int{0, 0, 0}},
|
||||
ans15{[][]int{[]int{0, 0, 0}}},
|
||||
ans15{[][]int{{0, 0, 0}}},
|
||||
},
|
||||
|
||||
question15{
|
||||
{
|
||||
para15{[]int{-1, 0, 1, 2, -1, -4}},
|
||||
ans15{[][]int{[]int{-1, 0, 1}, []int{-1, -1, 2}}},
|
||||
ans15{[][]int{{-1, 0, 1}, {-1, -1, 2}}},
|
||||
},
|
||||
|
||||
question15{
|
||||
{
|
||||
para15{[]int{-4, -2, -2, -2, 0, 1, 2, 2, 2, 3, 3, 4, 4, 6, 6}},
|
||||
ans15{[][]int{[]int{-4, -2, 6}, []int{-4, 0, 4}, []int{-4, 1, 3}, []int{-4, 2, 2}, []int{-2, -2, 4}, []int{-2, 0, 2}}},
|
||||
ans15{[][]int{{-4, -2, 6}, {-4, 0, 4}, {-4, 1, 3}, {-4, 2, 2}, {-2, -2, 4}, {-2, 0, 2}}},
|
||||
},
|
||||
|
||||
question15{
|
||||
{
|
||||
para15{[]int{5, -7, 3, -3, 5, -10, 4, 8, -3, -8, -3, -3, -1, -8, 6, 4, -4, 7, 2, -5, -2, -7, -3, 7, 2, 4, -6, 5}},
|
||||
ans15{[][]int{[]int{-10, 2, 8}, []int{-10, 3, 7}, []int{-10, 4, 6}, []int{-10, 5, 5}, []int{-8, 2, 6}, []int{-8, 3, 5}, []int{-8, 4, 4}, []int{-7, -1, 8},
|
||||
[]int{-7, 2, 5}, []int{-7, 3, 4}, []int{-6, -2, 8}, []int{-6, -1, 7}, []int{-6, 2, 4}, []int{-5, -3, 8}, []int{-5, -2, 7}, []int{-5, -1, 6}, []int{-5, 2, 3},
|
||||
[]int{-4, -3, 7}, []int{-4, -2, 6}, []int{-4, -1, 5}, []int{-4, 2, 2}, []int{-3, -3, 6}, []int{-3, -2, 5}, []int{-3, -1, 4}, []int{-2, -1, 3}}},
|
||||
ans15{[][]int{{-10, 2, 8}, {-10, 3, 7}, {-10, 4, 6}, {-10, 5, 5}, {-8, 2, 6}, {-8, 3, 5}, {-8, 4, 4}, {-7, -1, 8},
|
||||
{-7, 2, 5}, {-7, 3, 4}, {-6, -2, 8}, {-6, -1, 7}, {-6, 2, 4}, {-5, -3, 8}, {-5, -2, 7}, {-5, -1, 6}, {-5, 2, 3},
|
||||
{-4, -3, 7}, {-4, -2, 6}, {-4, -1, 5}, {-4, 2, 2}, {-3, -3, 6}, {-3, -2, 5}, {-3, -1, 4}, {-2, -1, 3}}},
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -11,6 +11,9 @@ func threeSumClosest(nums []int, target int) int {
|
||||
if n > 2 {
|
||||
sort.Ints(nums)
|
||||
for i := 0; i < n-2; i++ {
|
||||
if i > 0 && nums[i] == nums[i-1] {
|
||||
continue
|
||||
}
|
||||
for j, k := i+1, n-1; j < k; {
|
||||
sum := nums[i] + nums[j] + nums[k]
|
||||
if abs(sum-target) < diff {
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user