324 Commits

Author SHA1 Message Date
be6831e5e3 Revert "add: leetcode 0492 solution" 2021-11-06 19:07:44 -07:00
f09ea6cd09 Update README 2021-11-06 19:06:10 -07:00
7d3ba345f3 Merge pull request #176 from gostool/leetcode0301
add: leetcode 0301 solution
2021-11-06 18:42:02 -07:00
a3f71751eb Merge pull request #181 from novahe/master
update/0515: add other solution
2021-11-06 18:28:03 -07:00
2051a1b67c Merge pull request #182 from dotcom900825/patch-1
Minor typo fix
2021-11-06 18:26:51 -07:00
0a3c4d0ed8 Minor type fix 2021-11-06 09:34:41 -07:00
2608238acb update/0515: add other solution 2021-11-05 19:45:18 +08:00
7d08f48786 add: leetcode 0301 solution 2021-10-27 12:36:07 +08:00
af654b2e51 Update Chapter Two 2021-10-21 22:52:55 -07:00
796b4b6582 Update Chapter Two 2021-10-21 22:51:12 -07:00
9effade48f Update 0352 solution 2021-10-21 22:48:09 -07:00
44541dc0ef Merge pull request #173 from gostool/leetcode0352
add: leetcode 0352 solution
2021-10-21 22:17:51 -07:00
f68bec22d9 add: leetcode 0352 solution 2021-10-09 11:56:13 +08:00
0e69148802 Update 498 solution 2021-10-08 20:05:23 -07:00
819145dca6 Update 2021-10-08 20:02:46 -07:00
4b3ef8a97d Update 2021-10-08 20:02:14 -07:00
24ee84feaf Update 2021-10-08 20:01:23 -07:00
d3bb8b6279 Update 2021-10-08 20:00:27 -07:00
219c53bb03 Update 434 solution 2021-10-08 19:58:15 -07:00
16b1ab75bd Merge pull request #172 from gostool/leetcode0434
add: leetcode 0434 solution
2021-10-08 19:52:02 -07:00
325e5130b7 Update 212 solution 2021-10-08 19:50:33 -07:00
bde069b75e add: leetcode 0434 solution 2021-10-07 19:28:26 +08:00
f461eadb78 Update solution 0328 2021-09-17 23:41:06 -07:00
d32347137a Update solution 0058、0551、0958 2021-09-15 03:51:40 -07:00
71b771dc5d Add solution 0058 2021-09-15 03:22:09 -07:00
0d3b70571a Merge pull request #170 from gostool/leetcode0058
add: leetcode 0058 solution
2021-09-15 03:19:21 -07:00
bef7599068 Add solution 0551 2021-09-15 03:18:02 -07:00
3c11d93a29 add: leetcode 0058 solution 2021-09-15 17:04:01 +08:00
29880358f0 Merge pull request #166 from gostool/leetcode0551
add: leetcode 0551 solution
2021-09-14 23:49:07 -07:00
7db2a76fd6 Update solution 0445 2021-09-14 23:47:56 -07:00
5c0f4f9103 Merge pull request #167 from novahe/master
fix/445: add other solutions
2021-09-14 21:36:40 -07:00
3c85ef6e7a Update solution 0958 2021-09-14 21:25:13 -07:00
a2dcc00524 Update 2021-09-14 20:54:14 -07:00
f793b7aa48 Update 2021-09-14 20:49:29 -07:00
81d298f55c Update 2021-09-14 20:44:46 -07:00
07034111d5 Update 2021-09-14 20:40:50 -07:00
7acf5110db Update 2021-09-14 20:35:23 -07:00
50f90ec045 Update 2021-09-14 20:34:02 -07:00
1c71c1f0a5 Update 2021-09-14 20:33:19 -07:00
eec96cae11 Update 2021-09-14 20:32:12 -07:00
59c4b30d23 Update 2021-09-14 20:26:55 -07:00
c551601a99 Add solution 0958 2021-09-14 15:45:10 -07:00
086c7c9eda Merge pull request #168 from 3inchtime/958
add solution - 958
2021-09-14 15:37:16 -07:00
2e628eb33d Merge pull request #169 from zhufenggood/master
Update solution 0494.   Considering new edge test case.
2021-09-14 15:32:05 -07:00
a3f55d9560 Update solution 0494. Considering new edge test case. 2021-09-03 16:46:46 +08:00
e89003a2e3 Update solution 0494. Considering new edge test case. 2021-09-02 18:01:03 +08:00
61a586e96a Update solution 0494. Considering new edge test case. 2021-09-02 17:46:17 +08:00
e6bce61e81 add solution - 958 2021-08-30 23:22:14 +08:00
d1a87f1cbf fix/445: add other solution 2021-08-21 00:39:53 +08:00
5e49c8db0c Merge branch 'master' of https://github.com/halfrost/LeetCode-Go 2021-08-21 00:32:45 +08:00
daa7c7f044 fix/445: add other solution 2021-08-21 00:31:31 +08:00
d0f54e2bbd add: leetcode 0551 solution 2021-08-17 17:30:59 +08:00
2189396c54 Add solution 0677 2021-08-14 10:16:17 +08:00
4268f5837b Add solution 0429 2021-08-08 22:44:30 +08:00
a43125dc18 Add solution 1877 2021-08-08 20:33:36 +08:00
35530a4de4 Update solution 0116 2021-08-07 11:18:57 +08:00
d1e24bf344 Merge pull request #165 from 3inchtime/116
add 116 solution
2021-08-07 10:59:49 +08:00
6e74af9d6c Update solution 0106 2021-08-07 10:57:03 +08:00
33f616c7dc Merge pull request #163 from karminski/patch-2
Update 0106.Construct-Binary-Tree-from-Inorder-and-Postorder-Traversa…
2021-08-07 10:49:18 +08:00
c1d27a197b Update solution 0105 2021-08-07 10:48:43 +08:00
3de30e7848 Merge pull request #162 from karminski/patch-1
Update 0105.Construct-Binary-Tree-from-Preorder-and-Inorder-Traversal.md
2021-08-07 10:28:27 +08:00
e4505aab14 Update solution 1104 2021-08-07 10:27:48 +08:00
78f8879463 Merge pull request #161 from gostool/leetcode1104
add: leetcode 1104 solution
2021-08-07 10:12:52 +08:00
3755d3f251 Update solution 0018 2021-08-07 10:11:27 +08:00
ae5c145c3f Update solution 0016 2021-08-07 09:58:49 +08:00
07ddc128b4 Update solution 1877 2021-08-07 09:01:39 +08:00
674e50ba0d update solution 1877 2021-08-07 08:54:30 +08:00
2f2ba72e92 Update solution 0242 2021-08-07 08:49:07 +08:00
0547b8b075 Merge pull request #160 from brenobaptista/suggestion-242
Suggestion 242
2021-08-07 08:37:38 +08:00
040ac16526 Update solution 0543 2021-08-07 08:36:35 +08:00
1c662f4330 Merge pull request #159 from brenobaptista/solution-543
Added solution 543
2021-08-07 08:00:45 +08:00
765bb777e3 Update solution 0141 2021-08-07 07:23:55 +08:00
23beddc2b1 Merge pull request #157 from brenobaptista/cleaned-141
Cleaned 141
2021-08-06 21:49:24 +08:00
7b7a39291a add 116 solution 2021-08-05 23:34:31 +08:00
21e5e780cc Update 0106.Construct-Binary-Tree-from-Inorder-and-Postorder-Traversal.md
UPDATE a new answer for less memory cost & FIX method name typo.
2021-07-30 00:18:32 +08:00
97928e7abe Update 0105.Construct-Binary-Tree-from-Preorder-and-Inorder-Traversal.md
update a new answer for less memory cost.
2021-07-29 23:11:38 +08:00
28add7d729 add: leetcode 1104 solution 2021-07-29 11:58:29 +08:00
0823979d78 Suggestion for problem 242 2021-07-20 01:06:47 -03:00
c7d4051054 Added more tests 2021-07-20 01:05:56 -03:00
8b41ad38d3 Added English README 2021-07-19 22:42:27 -03:00
8c1235bdf1 Added tests for problem 543 2021-07-19 22:42:11 -03:00
dd26b1df3e Added solution 543 2021-07-19 22:41:51 -03:00
YDZ
02999e422e Update solution 1818 2021-07-19 04:12:39 +08:00
YDZ
82b544c664 Add solution 1818 2021-07-19 04:09:10 +08:00
YDZ
443b7ce63d Add solution 0611 2021-07-18 20:19:17 +08:00
YDZ
eda4953c3d Add solution 0791 2021-07-18 18:13:55 +08:00
YDZ
41b03831b3 Add solution 1846 2021-07-18 16:32:43 +08:00
da7f306dcb Added tests 2021-07-17 00:46:00 -03:00
c8aa2a477e Fixed definition 2021-07-17 00:36:07 -03:00
f5716a22aa Removed unnecessary condition 2021-07-17 00:32:50 -03:00
YDZ
185b1e1c3b Update 2021-07-11 18:59:30 +08:00
YDZ
c39400373d Update 2021-07-11 18:46:27 +08:00
YDZ
e04b83ff2c update solution 1006 2021-07-11 18:44:54 +08:00
YDZ
992ccf0054 Update 2021-07-03 21:33:49 +08:00
YDZ
cb6023e722 Update 2021-07-03 21:28:47 +08:00
YDZ
4af8e959b6 Update 2021-07-03 21:05:38 +08:00
YDZ
04679fe8bc Update solution 0168 2021-06-29 07:41:12 +08:00
YDZ
7a3db717e0 Update solution 0494 2021-06-28 16:42:33 +08:00
YDZ
38ffcbc1af Add solution 0135 2021-06-28 07:18:24 +08:00
YDZ
d5c5284b1a Update solution 0617 & Add solution 0752 2021-06-27 08:47:05 +08:00
bc7c912aa9 Merge pull request #155 from brenobaptista/solution-617
Added solution 617
2021-06-27 08:13:45 +08:00
YDZ
dbf56b5db8 Add solution 0909 2021-06-27 08:12:29 +08:00
127b852d7d Update solution 0234 2021-06-26 18:30:54 +08:00
cfb67acf6d Merge pull request #156 from brenobaptista/refactored-234
Refactored solution 234
2021-06-26 18:20:44 +08:00
f663cec583 Update ctl templates sorting 2021-06-26 18:20:04 +08:00
e216ed4430 Merge pull request #153 from brenobaptista/suggestion-202
Suggestion 202
2021-06-26 17:34:18 +08:00
7c7f09da99 Merge pull request #152 from brenobaptista/refactored-412
Refactored solution 412 using string concatenation
2021-06-26 17:29:37 +08:00
YDZ
a616d6ea09 Add solution 0576 2021-06-26 03:18:44 +08:00
5e6c9b1fc0 Refactored solution 234 2021-06-24 23:13:31 -03:00
44431beba4 Added English README for problem 617 2021-06-24 21:43:46 -03:00
1cef508aa3 Added tests for problem 617 2021-06-24 21:43:25 -03:00
21c05df2ba Added solution 617 2021-06-24 21:43:07 -03:00
YDZ
b11b8bf09c Update solution 0237 2021-06-24 02:36:57 +08:00
f94128417a Merge pull request #151 from brenobaptista/refactored-237
Refactored solution 237
2021-06-24 02:29:33 +08:00
YDZ
d1c6d8777a Update solution 0065 2021-06-24 02:27:20 +08:00
1198fcc279 Merge pull request #150 from ssezhangpeng/master
add leetcode_0065
2021-06-24 02:18:13 +08:00
YDZ
014e437944 Add solution 0792 2021-06-24 02:13:06 +08:00
1eb35d880f Suggestion for solution 202 2021-06-23 12:06:14 -03:00
c5a9c0fc5c Added a couple more test cases 2021-06-23 12:05:53 -03:00
8ae9b96b33 Refactored solution 412 using string concatenation 2021-06-22 11:00:36 -03:00
871204438b Refactored solution 237 2021-06-21 23:46:37 -03:00
cb1a2124a7 add leetcode_0065 2021-06-22 00:20:14 +08:00
820f3ddd28 add leetcode_0065 2021-06-22 00:12:44 +08:00
873183cc77 Merge branch 'master' of https://github.com/ssezhangpeng/LeetCode-Go-1 2021-06-22 00:02:44 +08:00
8741a38fe2 add leetcode_0065 2021-06-21 23:57:48 +08:00
b273c3f088 add leetcode_0064 2021-06-21 23:56:00 +08:00
578c85e416 Merge pull request #149 from brenobaptista/refactored-101
Refactored solution 101
2021-06-21 08:12:55 +08:00
804bf60609 Refactored solution 101 2021-06-20 19:53:41 -03:00
YDZ
75b8f85315 standardized question title 2021-06-20 16:55:57 +08:00
YDZ
c28e1c0267 Add solution 1600, change dir 0167、0303、0304、0307、0653、1017 2021-06-20 13:46:33 +08:00
YDZ
fe99f9d7d5 LeetCode delete problem 1204 cause ctl order error 2021-06-19 22:17:06 +08:00
YDZ
eb5eb51233 Add solution 1239 2021-06-19 20:28:57 +08:00
YDZ
4d91e41bef Add solution 0795 2021-06-19 19:48:35 +08:00
YDZ
7a90f3713d Update 0483 solution 2021-06-18 21:08:25 +08:00
555737bcff Add solution 0473 2021-06-16 18:16:04 +08:00
5cf1b806b1 Add solution 0279、0518 2021-06-16 17:38:56 +08:00
48cb642554 Add solution 0877 2021-06-16 16:22:56 +08:00
YDZ
fe13c6dc18 Add solution 0374 2021-06-14 02:03:55 +08:00
b2a4f39401 Add solution 0278 2021-06-13 20:12:01 +08:00
259eba0c84 Merge pull request #148 from novahe/fix/84
fix/84: easier to understand code
2021-06-12 17:15:19 +08:00
aa8912611f fix/84: clean up redundant code 2021-06-10 23:54:31 +08:00
YDZ
dbdc464dee Add solution 1383 2021-06-06 01:48:24 +08:00
YDZ
640dc700a6 Update solution 0069 2021-06-05 23:43:42 +08:00
d0c6f905f6 Merge pull request #146 from hanlins/69/sqrtx/consise-binary-search
Make the binary search solution more concise for Sqrt x
2021-06-05 23:40:24 +08:00
295504eb45 Merge pull request #145 from novahe/fix/209
fix/209: clean up redundant code
2021-06-05 23:33:54 +08:00
YDZ
cc78fdd0ef Add solution 0097、0523、0525、1465、1744 2021-06-04 16:22:35 +08:00
YDZ
c0191c235d Add solution 1268 2021-06-04 09:58:16 +08:00
60d3b04030 Make the binary search solution more concise for Sqrt x
Signed-off-by: Hanlin Shi <shihanlin9@gmail.com>
2021-06-03 16:22:35 -07:00
2104d8f332 fix/209: clean up redundant code 2021-06-04 00:37:02 +08:00
YDZ
ec597e285d Update info 2021-06-02 07:29:51 +08:00
YDZ
d61a0226b8 Update 0695 solution 2021-06-02 07:09:59 +08:00
135754159e Merge pull request #144 from novahe/fix/199
fix/199: clean up redundant code
2021-06-02 07:08:45 +08:00
9e357544d1 fix/199: clean up redundant code 2021-06-01 22:52:00 +08:00
3dac8b9e82 Merge pull request #143 from novahe/fix/150
clean up redundant code
2021-06-01 13:08:48 +08:00
YDZ
9fb39146b7 Update 0051 solution 2021-06-01 13:04:57 +08:00
e256d74761 Merge pull request #142 from hanlins/51/n-queen/bit-operation
Add solution for N-Queen problem which uses bit-operation
2021-06-01 12:57:21 +08:00
5cd43244e9 clean up redundant code 2021-05-31 23:40:55 +08:00
cff768e63c Add solution for N-Queen problem which uses bit-operation
Still uses DFS, optimized for state compression.

Signed-off-by: Hanlin Shi <shihanlin9@gmail.com>
2021-05-31 00:43:43 -07:00
YDZ
ad3dfff270 update 0129 solution 2021-05-30 09:19:41 +08:00
7ca6279850 Merge pull request #141 from novahe/fix/129
update 129
2021-05-30 09:14:07 +08:00
44eddae9d0 update 129 2021-05-29 21:01:30 +08:00
YDZ
95eddf7a24 Update solution 0024 2021-05-29 03:30:08 +08:00
889e495992 Merge pull request #140 from hanlins/24/one-liner
Use a concise solution for problem 24 swap nodes in pairs
2021-05-28 13:29:41 +08:00
22e9be3663 Use a concise solution for problem 24 swap nodes in pairs
Signed-off-by: Hanlin Shi <shihanlin9@gmail.com>
2021-05-27 09:48:36 -07:00
YDZ
11f3e13688 Add solution 1190 2021-05-27 11:00:10 +08:00
315d4fa8d8 Merge pull request #139 from NovaHe/fix/91
Fix/91 and 80
2021-05-26 00:47:31 +08:00
7a3fe1fed2 add 80 solution explain 2021-05-25 22:21:37 +08:00
YDZ
00b6d1a6ca Add solution 709 2021-05-25 02:07:37 +08:00
38875b19fb update 91 2021-05-24 23:16:08 +08:00
44c68a333a update 80 2021-05-23 17:25:26 +08:00
6d2d38e124 Merge pull request #138 from NovaHe/fix/75
clean up redundant code
2021-05-23 16:28:04 +08:00
851e0eaad5 Merge pull request #137 from NovaHe/master
clean up redundant code
2021-05-23 16:24:16 +08:00
d5aacae9d2 clean up redundant code 2021-05-23 14:30:33 +08:00
58f6f7fedb clean up 62 2021-05-23 13:19:27 +08:00
YDZ
9dbefba7cd Add solution 0810 2021-05-22 22:40:52 +08:00
991cb6e3d7 Merge pull request #133 from NovaHe/fix/48
fix/48: clean up code
2021-05-22 21:31:25 +08:00
YDZ
4330393c9b Update solution 1572 2021-05-22 21:29:38 +08:00
cd5572f250 Merge pull request #135 from gostool/leetcode1572
add: leetcode 1572 solution
2021-05-22 21:18:21 +08:00
YDZ
776fe07932 Add solution 0609、0692、0890、1048、1442、1738 2021-05-22 20:15:28 +08:00
36f3a4c757 add: leetcode 1572 solution 2021-05-21 16:48:31 +08:00
YDZ
86370c1ac5 Add solution 0462 2021-05-20 23:55:27 +08:00
bb50f33fec fix/48: clean up code 2021-05-20 00:04:27 +08:00
YDZ
be276a58dc update test case 2021-05-17 01:30:46 +08:00
0d64196cf1 Merge pull request #132 from NovaHe/fix/19
fix/19: clean up code
2021-05-17 01:22:55 +08:00
5e77733f1a fix/19: clean up code 2021-05-16 17:48:21 +08:00
YDZ
851946dc9a Update solution 0003 2021-05-13 16:14:13 +08:00
e72e4cb599 Merge pull request #130 from NovaHe/fix/3
fix/3: clean up code
2021-05-13 15:58:52 +08:00
YDZ
40201dceb1 Add solution 0816 2021-05-13 15:51:26 +08:00
YDZ
e3304f5a83 Add solution 1310 2021-05-12 23:14:26 +08:00
3c1176be43 fix/3: clean up code 2021-05-12 21:29:15 +08:00
YDZ
012999a33b Add solution 1734 2021-05-11 03:32:45 +08:00
2a164310be Merge pull request #128 from halfrost/add_toc
Add toc
2021-05-11 00:25:05 +08:00
YDZ
9347140480 Add toc 2021-05-11 00:23:33 +08:00
YDZ
87c5b40454 Add Time_Complexity 2021-05-10 23:15:26 +08:00
YDZ
9a30c0094e Add solution 0583、1482 2021-05-09 18:47:59 +08:00
YDZ
09c6e478e1 Update 0215 solution 2021-05-09 16:52:24 +08:00
YDZ
98c5414092 Add solution 630 2021-05-09 09:17:12 +08:00
YDZ
76753e8ca6 Update solution 0874 2021-05-08 16:29:09 +08:00
a10cebc033 Merge pull request #125 from NovaHe/feature/874
feature/874: add 874 solution
2021-05-08 16:15:20 +08:00
YDZ
5f6ea09570 Add solution 1486 2021-05-08 16:12:00 +08:00
2a115eccc3 Merge pull request #127 from NovaHe/fix/345
fix/345: clean up redundant code
2021-05-05 22:36:45 +08:00
2450cf4dd0 fix/345: clean up redundant code 2021-05-05 12:01:03 +08:00
1835b6dd45 feature/874: add 874 solution 2021-05-04 21:36:26 +08:00
YDZ
24829288bb Update 0821 solution 2021-05-04 21:13:20 +08:00
624a9ae9e6 Merge pull request #124 from NovaHe/feature/821
feature/821: add O(n) solution
2021-05-04 21:01:32 +08:00
YDZ
70aafb68d4 update 137 solution 2021-05-04 21:00:43 +08:00
0c817666f5 feature/821: add O(n) solution 2021-05-04 17:19:18 +08:00
YDZ
99fe55c7df Update 0437 2021-05-04 10:28:14 +08:00
65f4c4f060 Merge pull request #122 from NovaHe/feature/437
feature/437: add a faster solution
2021-05-04 09:42:51 +08:00
1071ae0455 Merge pull request #123 from halfrost/Update_hugo_book_V9
Update hugo book to V9
2021-05-04 09:37:55 +08:00
YDZ
3d5df51382 Notable changes:
Collapsed menus can be navigated without changing page!
Most SCSS vars were migration to CSS vars.
MermaidJS configuration can be customized.
Lead image can be now added to posts via image: frontmatter.
New partials: before and after toc.

New translations:
Traditional Chinese (#335)
Turkish (#300)

Other changes and fixes:
Post title rendering is now using proper partial.
Collapsible menus are now changing arrow on toggle (#332).
Link to SCM is now pointing to main branch by default.
Edit link can be more customized.
Bug Fix: Empty .Site.Params.contentDir (#312)
Button shortcode can now render markdown (#308)
Set default content direction to ltr (#307)
New 'BookOnlyTranslated' property to display only links to translated pages (#303)
MermaidJS upgraded to v8.9.0 (#305)
New page param: bookSearchExclude to exclude pages from search index
2021-05-04 09:29:55 +08:00
4abb13e6ca feature/437: add a faster solution 2021-05-02 17:54:54 +08:00
YDZ
9c0603ea84 Update 0401 2021-05-02 11:38:13 +08:00
dd99c2c7e1 Merge pull request #120 from NovaHe/feature/401
feature/401: add a simpler solution
2021-05-02 11:36:11 +08:00
bff8947a8b fix 401: add a simpler solution 2021-05-02 10:47:14 +08:00
YDZ
678bc75719 Add solution 0554 2021-05-02 04:15:16 +08:00
86856f687a Merge pull request #119 from NovaHe/fix/263
fix 263: remove redundant compute
2021-05-01 01:46:02 +08:00
YDZ
1eb4bf698a Add solution 690 2021-05-01 01:31:56 +08:00
594af3f4d8 fix 263: remove redundant compute 2021-05-01 00:24:53 +08:00
YDZ
0f1bb00e62 Update 0167、0169 2021-04-28 09:34:02 +08:00
01ce0fd9b1 Merge pull request #118 from yangwenmai/patch-1
Update LRUCache.md
2021-04-28 09:12:33 +08:00
099e31ea64 Merge pull request #117 from NovaHe/master
fix 167: clean up redundant code
2021-04-28 09:12:20 +08:00
97b5aaf1c2 Update LRUCache.md 2021-04-28 09:03:45 +08:00
YDZ
87c8048afb Add solution 0938、1642 2021-04-28 08:40:36 +08:00
2d5005a24a fix 169: clean up redundant code 2021-04-27 21:14:09 +08:00
263ca6e3b7 fix 167: clean up redundant code 2021-04-27 12:57:45 +08:00
8f1f1db6f2 Merge branch 'master' of https://github.com/halfrost/LeetCode-Go 2021-04-27 12:55:05 +08:00
0a614a0e79 fix 167: clean up redundant code 2021-04-27 12:53:02 +08:00
YDZ
d27ca9bd0a Add solution 1353 2021-04-26 02:48:16 +08:00
YDZ
6fcc9ec669 Update 0048、1011 2021-04-26 01:24:48 +08:00
YDZ
0a87bb5a02 Update 0218 2021-04-25 12:29:32 +08:00
YDZ
f92ac03f8f Update Segment Tree 2021-04-25 10:58:14 +08:00
YDZ
4be7d82168 Update Segment Tree 2021-04-24 22:30:03 +08:00
YDZ
45fb40ee7f Add solution 0368、0377、0696 2021-04-24 21:04:28 +08:00
YDZ
1cdbefdc9c Update bit 2021-04-24 01:15:33 +08:00
YDZ
fd409dcbd1 Update bit 2021-04-23 17:20:59 +08:00
YDZ
8a14f2c734 Update solution 0307 2021-04-22 20:36:55 +08:00
YDZ
732095c59a Update 0315、0327 2021-04-22 18:44:06 +08:00
YDZ
d4d5a20eb1 Update solution 1649、493 2021-04-22 17:07:22 +08:00
YDZ
e0aed6a035 Add bit template 2021-04-22 10:13:39 +08:00
YDZ
19e5c7e9c9 Update bit 2021-04-22 00:15:58 +08:00
YDZ
ebd8951db4 Add solution 0589 2021-04-21 16:43:25 +08:00
YDZ
4e6a1e3287 Update 2021-04-20 11:24:07 +08:00
YDZ
370ec68c76 Update bit 2021-04-19 16:58:27 +08:00
YDZ
8ee289c17c Update 0101 2021-04-19 10:21:24 +08:00
5fbca5f096 Merge pull request #116 from NovaHe/master
fix 101: refactor code
2021-04-19 09:58:09 +08:00
YDZ
4c59f10469 Add BIT 2021-04-18 02:13:15 +08:00
YDZ
18e6d08e93 Add solution 1209 2021-04-17 15:28:07 +08:00
784e731c77 fix 101: refactor code 2021-04-17 10:46:10 +08:00
YDZ
09463eee6f Add 0088 test case 2021-04-17 08:24:40 +08:00
ec4cc41102 Merge pull request #115 from NovaHe/master
fix 88: clean up redundant code
2021-04-17 08:07:50 +08:00
d3c556bb5d fix 88: clean up redundant code 2021-04-17 00:20:14 +08:00
YDZ
86fac4e139 Update 0019、0066 2021-04-16 00:12:51 +08:00
7f0a3b514f Merge pull request #114 from NovaHe/master
fix 66: clean up redundant code
2021-04-16 00:09:27 +08:00
7cbef318e1 fix 66: clean up redundant code 2021-04-15 23:01:21 +08:00
YDZ
541ec13f70 Add test case 2021-04-15 20:59:52 +08:00
8b5785532a Merge pull request #113 from mfzzz/master
Update 19. Remove Nth Node From End of List.go
2021-04-15 20:45:19 +08:00
858198e385 Update 19. Remove Nth Node From End of List.go
fix: when m(length of linkList) is 1 and n greater than m, will cause "nil pointer dereference"
2021-04-15 02:35:26 +08:00
YDZ
d47c2ec4c3 Add solution 0530、783 2021-04-14 00:56:16 +08:00
YDZ
8ded561341 Add solution 0667 2021-04-13 13:09:06 +08:00
YDZ
a8f9bfb98c Add solution 0264 2021-04-12 10:24:30 +08:00
YDZ
1376328b0b Update solution 0066 2021-04-10 17:40:24 +08:00
YDZ
dab1f90a2f Update 2021-04-10 17:29:59 +08:00
YDZ
ce600d6822 Add solution 1551 2021-04-07 09:27:32 +08:00
f376eaf316 Merge pull request #109 from tntC4stl3/problem226
修复226题单元测试的问题
2021-04-07 08:31:20 +08:00
a15f91f029 Fix problem 226 test case 2021-04-06 23:35:10 +08:00
YDZ
a6ee37ebef Add solution 0775 2021-04-06 03:26:08 +08:00
YDZ
eb2331edb6 Add solution 0622 2021-04-05 00:39:16 +08:00
YDZ
c5a6ac4b11 Add solution 1143 2021-04-04 10:47:45 +08:00
YDZ
58dcf6b469 Add solution 0032 2021-04-04 09:44:52 +08:00
ce93f89531 Merge pull request #107 from NovaHe/fix/102
fix 0102:  优化代码,清除冗余代码
2021-04-01 21:46:23 +08:00
YDZ
6d37f59f97 Add solution 1006 2021-04-01 20:27:27 +08:00
YDZ
9bd6121476 Update solution 924 2021-04-01 18:17:34 +08:00
99cea18cc6 fix 0102: clean up redundant code 2021-03-31 18:50:05 +08:00
YDZ
d798338426 Add solution 0970 2021-03-30 07:59:48 +08:00
YDZ
3fc7e9c543 Add solution 0423 2021-03-29 01:00:08 +08:00
YDZ
984b06f29c Update solution 0372 2021-03-29 00:05:28 +08:00
YDZ
417635f58c Update solution 297 2021-03-28 14:48:41 +08:00
aa5bccb403 Merge pull request #105 from saenaii/leetcode_297
added leetcode 297
2021-03-28 14:36:25 +08:00
YDZ
b4d7a80343 Add solution 647 2021-03-28 12:01:36 +08:00
e10eaa99f8 added leetcode 297 2021-03-27 19:30:25 +08:00
YDZ
427b25d4b7 Add solution 417、916 2021-03-27 02:31:31 +08:00
YDZ
1781d4e7a5 Add solution 870 2021-03-27 00:30:54 +08:00
YDZ
0c519027d4 Add solution 341 2021-03-24 11:36:45 +08:00
YDZ
fec98dba7f Add solution 966 2021-03-23 16:51:57 +08:00
YDZ
613fa9aa92 Add solution 869 2021-03-22 00:22:28 +08:00
YDZ
fe7d9845bd Add solution 1396 2021-03-20 18:33:14 +08:00
YDZ
23a0f0a2b4 Add solution 376 2021-03-19 12:17:24 +08:00
YDZ
031d96b369 Add solution 478 2021-03-17 18:48:26 +08:00
YDZ
1cd9cec988 Add solution 115 2021-03-17 18:10:13 +08:00
YDZ
89af12786a update solution 103 2021-03-16 14:30:02 +08:00
YDZ
c92b576018 Add solution 535 2021-03-15 22:56:38 +08:00
096f514b66 Merge pull request #103 from thomasrockhu/codecov-badge
Add Codecov badge to README
2021-03-15 12:22:33 +08:00
YDZ
6cbaad13b1 modify solution 76 2021-03-15 12:14:14 +08:00
YDZ
c30c6c7f41 Add solution 1461、1721 2021-03-15 10:47:36 +08:00
YDZ
943d558ca8 Add solution 823 2021-03-14 16:22:28 +08:00
53e10a59c1 Add Codecov badge to README 2021-03-12 23:40:03 -05:00
YDZ
8bb84f2edc Add solution 43、45、73、227 2021-03-11 21:51:36 +08:00
YDZ
a841eac968 Add solution 6、8、12 2021-03-10 23:35:16 +08:00
YDZ
1eac64966f Add solution 623 2021-03-09 22:30:36 +08:00
YDZ
2e7dd977c4 Add solution 1332 2021-03-09 01:50:48 +08:00
YDZ
11e38a651e Add solution 0820 2021-03-07 01:32:04 +08:00
YDZ
21fda4f75f Fix 0009 solution 2021-03-04 14:15:46 +08:00
YDZ
3f3026ca05 Update solution 1178 2021-03-04 03:34:47 +08:00
66e690a277 Merge pull request #102 from kingeasternsun/master
add leetcode 1178 solution
2021-03-04 03:16:28 +08:00
YDZ
87c1060ef5 Add solution 0005 2021-03-04 03:11:42 +08:00
ee741232d4 add leetcode 1178 solution 2021-03-03 16:30:51 +08:00
YDZ
f0c5270f84 Add solution 0304 2021-03-03 02:21:34 +08:00
YDZ
a7a40da0aa Add solution 0395 2021-03-01 20:11:55 +08:00
YDZ
b4eab90b74 Fix 303、307、167、653、1017 multi ‘--’ cause link bad 2021-02-27 00:44:59 +08:00
YDZ
c839a96874 Add solution 0581 2021-02-26 00:45:05 +08:00
YDZ
cf841b821b Add solution 0991 2021-02-21 21:21:23 +08:00
YDZ
fd62b9f721 Add solution 1438 2021-02-21 11:45:33 +08:00
YDZ
d12dde092f Fix 0019 2021-02-21 08:38:32 +08:00
075d7ba884 Merge pull request #101 from leizhiyuan/patch-1
Update 0215.Kth-Largest-Element-in-an-Array.md
2021-02-20 17:13:49 +08:00
4dc97cd730 Update 0215.Kth-Largest-Element-in-an-Array.md 2021-02-20 16:37:27 +08:00
YDZ
6c7d4fb59a Add solution 413、1249 2021-02-20 13:44:38 +08:00
YDZ
28b422f87f Update 2021-02-20 01:42:06 +08:00
8e01a1c176 Merge pull request #100 from WeeHong/feat/add_english_translate
Add english translation 添加英文翻译
2021-02-20 01:33:26 +08:00
YDZ
2af901862f Fix 1093 LaTeX 2021-02-20 01:27:21 +08:00
5a2331afd4 Add english translation 添加英文翻译 2021-02-19 22:11:35 +08:00
YDZ
be7fe42dcd fix sort time complexity 2021-02-17 20:17:09 +08:00
YDZ
86e61e9dc6 Add solution 1337 2021-02-16 04:07:46 +08:00
YDZ
917d613465 Add solution 1603、1608、1700、1710、1716、1720、1725、1732、1736、1742、1748、1752、1758 2021-02-16 01:37:40 +08:00
859 changed files with 40181 additions and 4501 deletions

1
.gitignore vendored
View File

@ -1 +1,2 @@
*.toml
.idea

3769
README.md

File diff suppressed because it is too large Load Diff

View File

@ -4,20 +4,21 @@ import (
"bufio"
"errors"
"fmt"
"github.com/halfrost/LeetCode-Go/ctl/util"
"github.com/spf13/cobra"
"io"
"io/ioutil"
"os"
"regexp"
"strings"
"github.com/halfrost/LeetCode-Go/ctl/util"
"github.com/spf13/cobra"
)
var (
chapterOneFileOrder = []string{"_index", "Data_Structure", "Algorithm"}
chapterOneMenuOrder = []string{"_index", "#关于作者", "Data_Structure", "Algorithm"}
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", "Sort", "Bit_Manipulation", "Union_Find", "Sliding_Window", "Segment_Tree", "Binary_Indexed_Tree"}
"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>"
@ -34,10 +35,10 @@ var (
chapterMap = map[string]map[string]string{
"ChapterOne": {
"_index": "第一章 序章",
"#关于作者": "1.1 关于作者",
"Data_Structure": "1.2 数据结构知识",
"Algorithm": "1.3 算法知识",
"_index": "第一章 序章",
"Data_Structure": "1.1 数据结构知识",
"Algorithm": "1.2 算法知识",
"Time_Complexity": "1.3 时间复杂度",
},
"ChapterTwo": {
"_index": "第二章 算法专题",
@ -54,7 +55,7 @@ var (
"Binary_Search": "2.11 Binary Search",
"Math": "2.12 Math",
"Hash_Table": "2.13 Hash Table",
"Sort": "2.14 ✅ Sort",
"Sorting": "2.14 ✅ Sorting",
"Bit_Manipulation": "2.15 ✅ Bit Manipulation",
"Union_Find": "2.16 ✅ Union Find",
"Sliding_Window": "2.17 ✅ Sliding Window",

View File

@ -1,7 +1,7 @@
|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) |❤️|

View File

@ -18,15 +18,38 @@ type Mdrow struct {
// 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++ {
id := mdrows[solutionIds[i]-1].FrontendQuestionID
if solutionIds[i] == int(id) {
//fmt.Printf("id = %v i = %v solutionIds = %v\n", id, i, solutionIds[i])
mdrows[id-1].SolutionPath = fmt.Sprintf("[Go](https://github.com/halfrost/LeetCode-Go/tree/master/leetcode/%v)", fmt.Sprintf("%04d.%v", id, strings.Replace(strings.TrimSpace(mdrows[id-1].QuestionTitle), " ", "-", -1)))
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("序号出错了 solutionIds = %v id = %v\n", solutionIds[i], id)
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 | |

View File

@ -115,6 +115,41 @@ 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{}
@ -123,13 +158,7 @@ func GenerateTagMdRows(solutionIds []int, metaMap map[int]TagList, mdrows []Mdro
tmp := TagList{}
tmp.FrontendQuestionID = row.FrontendQuestionID
tmp.QuestionTitle = strings.TrimSpace(row.QuestionTitle)
s1 := strings.Replace(tmp.QuestionTitle, " ", "-", -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)
s7 := standardizedTitle(row.QuestionTitle, row.FrontendQuestionID)
if internal {
tmp.SolutionPath = fmt.Sprintf("[Go]({{< relref \"/ChapterFour/%v/%v.md\" >}})", util.GetChpaterFourFileNum(int(row.FrontendQuestionID)), fmt.Sprintf("%04d.%v", int(row.FrontendQuestionID), s7))
} else {

View File

@ -18,11 +18,11 @@ import (
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", "Sort", "Bit Manipulation", "Union Find", "Sliding Window", "Segment Tree", "Binary Indexed Tree"}
"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", "Sort", "Bit_Manipulation", "Union_Find", "Sliding_Window", "Segment_Tree", "Binary_Indexed_Tree"}
"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", "sort", "bit-manipulation", "union-find", "sliding-window", "segment-tree", "binary-indexed-tree"}
"binary-search", "math", "hash-table", "sorting", "bit-manipulation", "union-find", "sliding-window", "segment-tree", "binary-indexed-tree"}
)
func newBuildCommand() *cobra.Command {

View File

@ -1,10 +1,10 @@
---
title: 2.14 ✅ Sort
title: 2.14 ✅ Sorting
type: docs
weight: 14
---
# Sort
# Sorting
![](https://img.halfrost.com/Leetcode/Sort.png)

View File

@ -16,6 +16,7 @@
<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">

View File

@ -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,7 +27,7 @@ func lengthOfLongestSubstring(s string) int {
}
// 解法二 滑动窗口
func lengthOfLongestSubstring_(s string) int {
func lengthOfLongestSubstring1(s string) int {
if len(s) == 0 {
return 0
}
@ -47,6 +47,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

View File

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

View File

@ -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`。图示见下图:

View File

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

View File

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

View 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)。
![https://img.halfrost.com/Leetcode/leetcode_5_1.png](https://img.halfrost.com/Leetcode/leetcode_5_1.png)
- 首先是预处理,向字符串的头尾以及每两个字符中间添加一个特殊字符 `#`,比如字符串 `aaba` 处理后会变成 `#a#a#b#a#`。那么原先长度为偶数的回文字符串 `aa` 会变成长度为奇数的回文字符串 `#a#a#`,而长度为奇数的回文字符串 `aba` 会变成长度仍然为奇数的回文字符串 `#a#b#a#`,经过预处理以后,都会变成长度为奇数的字符串。**注意这里的特殊字符不需要是没有出现过的字母,也可以使用任何一个字符来作为这个特殊字符。**这是因为,当我们只考虑长度为奇数的回文字符串时,每次我们比较的两个字符奇偶性一定是相同的,所以原来字符串中的字符不会与插入的特殊字符互相比较,不会因此产生问题。**预处理以后,以某个中心扩散的步数和实际字符串长度是相等的。**因为半径里面包含了插入的特殊字符,又由于左右对称的性质,所以扩散半径就等于原来回文子串的长度。
![https://img.halfrost.com/Leetcode/leetcode_5_2.png](https://img.halfrost.com/Leetcode/leetcode_5_2.png)
- 核心部分是如何通过左边已经扫描过的数据推出右边下一次要扩散的中心。这里定义下一次要扩散的中心下标是 `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
}
```

View 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)
}

View 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")
}

View 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)
}
```

View File

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

View File

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

View 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)
}
```

View File

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

View File

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

View 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
}

View 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")
}

View 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
}
```

View File

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

View File

@ -2,7 +2,92 @@ package leetcode
import "sort"
func fourSum(nums []int, target int) [][]int {
// 解法一 双指针
func fourSum(nums []int, target int) (quadruplets [][]int) {
sort.Ints(nums)
n := len(nums)
for i := 0; i < n-3 && nums[i]+nums[i+1]+nums[i+2]+nums[i+3] <= target; i++ {
if i > 0 && nums[i] == nums[i-1] || nums[i]+nums[n-3]+nums[n-2]+nums[n-1] < target {
continue
}
for j := i + 1; j < n-2 && nums[i]+nums[j]+nums[j+1]+nums[j+2] <= target; j++ {
if j > i+1 && nums[j] == nums[j-1] || nums[i]+nums[j]+nums[n-2]+nums[n-1] < target {
continue
}
for left, right := j+1, n-1; left < right; {
if sum := nums[i] + nums[j] + nums[left] + nums[right]; sum == target {
quadruplets = append(quadruplets, []int{nums[i], nums[j], nums[left], nums[right]})
for left++; left < right && nums[left] == nums[left-1]; left++ {
}
for right--; left < right && nums[right] == nums[right+1]; right-- {
}
} else if sum < target {
left++
} else {
right--
}
}
}
}
return
}
// 解法二 kSum
func fourSum1(nums []int, target int) [][]int {
res, cur := make([][]int, 0), make([]int, 0)
sort.Ints(nums)
kSum(nums, 0, len(nums)-1, target, 4, cur, &res)
return res
}
func kSum(nums []int, left, right int, target int, k int, cur []int, res *[][]int) {
if right-left+1 < k || k < 2 || target < nums[left]*k || target > nums[right]*k {
return
}
if k == 2 {
// 2 sum
twoSum(nums, left, right, target, cur, res)
} else {
for i := left; i < len(nums); i++ {
if i == left || (i > left && nums[i-1] != nums[i]) {
next := make([]int, len(cur))
copy(next, cur)
next = append(next, nums[i])
kSum(nums, i+1, len(nums)-1, target-nums[i], k-1, next, res)
}
}
}
}
func twoSum(nums []int, left, right int, target int, cur []int, res *[][]int) {
for left < right {
sum := nums[left] + nums[right]
if sum == target {
cur = append(cur, nums[left], nums[right])
temp := make([]int, len(cur))
copy(temp, cur)
*res = append(*res, temp)
// reset cur to previous state
cur = cur[:len(cur)-2]
left++
right--
for left < right && nums[left] == nums[left-1] {
left++
}
for left < right && nums[right] == nums[right+1] {
right--
}
} else if sum < target {
left++
} else {
right--
}
}
}
// 解法三
func fourSum2(nums []int, target int) [][]int {
res := [][]int{}
counter := map[int]int{}
for _, value := range nums {

View File

@ -17,22 +17,18 @@ type ListNode = structures.ListNode
// 解法一
func removeNthFromEnd(head *ListNode, n int) *ListNode {
var fast, slow *ListNode
fast = head
slow = head
for i := 0; i < n; i++ {
dummyHead := &ListNode{Next: head}
preSlow, slow, fast := dummyHead, head, head
for fast != nil {
if n <= 0 {
preSlow = slow
slow = slow.Next
}
n--
fast = fast.Next
}
if fast == nil {
head = head.Next
return head
}
for fast.Next != nil {
fast = fast.Next
slow = slow.Next
}
slow.Next = slow.Next.Next
return head
preSlow.Next = slow.Next
return dummyHead.Next
}
// 解法二

View File

@ -29,6 +29,26 @@ func Test_Problem19(t *testing.T) {
qs := []question19{
{
para19{[]int{1}, 3},
ans19{[]int{1}},
},
{
para19{[]int{1, 2}, 2},
ans19{[]int{2}},
},
{
para19{[]int{1}, 1},
ans19{[]int{}},
},
{
para19{[]int{1, 2, 3, 4, 5}, 10},
ans19{[]int{1, 2, 3, 4, 5}},
},
{
para19{[]int{1, 2, 3, 4, 5}, 1},
ans19{[]int{1, 2, 3, 4}},

View File

@ -2,16 +2,44 @@
## 题目
Given a linked list, remove the n-th node from the end of list and return its head.
Given the `head` of a linked list, remove the `nth` node from the end of the list and return its head.
Example:
**Follow up:** Could you do this in one pass?
**Example 1:**
![](https://assets.leetcode.com/uploads/2020/10/03/remove_ex1.jpg)
```
Given linked list: 1->2->3->4->5, and n = 2.
Input: head = [1,2,3,4,5], n = 2
Output: [1,2,3,5]
After removing the second node from the end, the linked list becomes 1->2->3->5.
```
**Example 2:**
```
Input: head = [1], n = 1
Output: []
```
**Example 3:**
```
Input: head = [1,2], n = 1
Output: [1]
```
**Constraints:**
- The number of nodes in the list is `sz`.
- `1 <= sz <= 30`
- `0 <= Node.val <= 100`
- `1 <= n <= sz`
## 题目大意
删除链表中倒数第 n 个结点。

View File

@ -16,30 +16,9 @@ type ListNode = structures.ListNode
*/
func swapPairs(head *ListNode) *ListNode {
if head == nil || head.Next == nil {
return head
dummy := &ListNode{Next: head}
for pt := dummy; pt != nil && pt.Next != nil && pt.Next.Next != nil; {
pt, pt.Next, pt.Next.Next, pt.Next.Next.Next = pt.Next, pt.Next.Next, pt.Next.Next.Next, pt.Next
}
s := head.Next
var behind *ListNode
for head.Next != nil {
headNext := head.Next
if behind != nil && behind.Next != nil {
behind.Next = headNext
}
var next *ListNode
if head.Next.Next != nil {
next = head.Next.Next
}
if head.Next.Next != nil {
head.Next = next
} else {
head.Next = nil
}
headNext.Next = head
behind = head
if head.Next != nil {
head = next
}
}
return s
return dummy.Next
}

View File

@ -0,0 +1,58 @@
package leetcode
// 解法一 栈
func longestValidParentheses(s string) int {
stack, res := []int{}, 0
stack = append(stack, -1)
for i := 0; i < len(s); i++ {
if s[i] == '(' {
stack = append(stack, i)
} else {
stack = stack[:len(stack)-1]
if len(stack) == 0 {
stack = append(stack, i)
} else {
res = max(res, i-stack[len(stack)-1])
}
}
}
return res
}
func max(a, b int) int {
if a > b {
return a
}
return b
}
// 解法二 双指针
func longestValidParentheses1(s string) int {
left, right, maxLength := 0, 0, 0
for i := 0; i < len(s); i++ {
if s[i] == '(' {
left++
} else {
right++
}
if left == right {
maxLength = max(maxLength, 2*right)
} else if right > left {
left, right = 0, 0
}
}
left, right = 0, 0
for i := len(s) - 1; i >= 0; i-- {
if s[i] == '(' {
left++
} else {
right++
}
if left == right {
maxLength = max(maxLength, 2*left)
} else if left > right {
left, right = 0, 0
}
}
return maxLength
}

View File

@ -0,0 +1,61 @@
package leetcode
import (
"fmt"
"testing"
)
type question32 struct {
para32
ans32
}
// para 是参数
// one 代表第一个参数
type para32 struct {
s string
}
// ans 是答案
// one 代表第一个答案
type ans32 struct {
one int
}
func Test_Problem32(t *testing.T) {
qs := []question32{
{
para32{"(()"},
ans32{2},
},
{
para32{")()())"},
ans32{4},
},
{
para32{"()(())"},
ans32{6},
},
{
para32{"()(())))"},
ans32{6},
},
{
para32{"()(()"},
ans32{2},
},
}
fmt.Printf("------------------------Leetcode Problem 32------------------------\n")
for _, q := range qs {
_, p := q.ans32, q.para32
fmt.Printf("【input】:%v 【output】:%v\n", p, longestValidParentheses(p.s))
}
fmt.Printf("\n\n\n")
}

View File

@ -0,0 +1,108 @@
# [32. Longest Valid Parentheses](https://leetcode.com/problems/longest-valid-parentheses/)
## 题目
Given a string containing just the characters `'('` and `')'`, find the length of the longest valid (well-formed) parentheses substring.
**Example 1:**
```
Input: s = "(()"
Output: 2
Explanation: The longest valid parentheses substring is "()".
```
**Example 2:**
```
Input: s = ")()())"
Output: 4
Explanation: The longest valid parentheses substring is "()()".
```
**Example 3:**
```
Input: s = ""
Output: 0
```
**Constraints:**
- `0 <= s.length <= 3 * 104`
- `s[i]` is `'('`, or `')'`.
## 题目大意
给你一个只包含 '(' 和 ')' 的字符串,找出最长有效(格式正确且连续)括号子串的长度。
## 解题思路
- 提到括号匹配,第一时间能让人想到的就是利用栈。这里需要计算嵌套括号的总长度,所以栈里面不能单纯的存左括号,而应该存左括号在原字符串的下标,这样通过下标相减可以获取长度。那么栈如果是非空,栈底永远存的是当前遍历过的字符串中**上一个没有被匹配的右括号的下标**。**上一个没有被匹配的右括号的下标**可以理解为每段括号匹配之间的“隔板”。例如,`())((()))`,第三个右括号,即为左右 2 段正确的括号匹配中间的“隔板”。“隔板”的存在影响计算最长括号长度。如果不存在“隔板”,前后 2 段正确的括号匹配应该“融合”在一起,最长长度为 `2 + 6 = 8`,但是这里存在了“隔板”,所以最长长度仅为 `6`
- 具体算法实现,遇到每个 `'('` ,将它的下标压入栈中。对于遇到的每个 `')'`,先弹出栈顶元素表示匹配了当前右括号。如果栈为空,说明当前的右括号为没有被匹配的右括号,于是将其下标放入栈中来更新**上一个没有被匹配的右括号的下标**。如果栈不为空,当前右括号的下标减去栈顶元素即为以该右括号为结尾的最长有效括号的长度。需要注意初始化时,不存在**上一个没有被匹配的右括号的下标**,那么将 `-1` 放入栈中,充当下标为 `0` 的“隔板”。时间复杂度 O(n),空间复杂度 O(n)。
- 在栈的方法中,实际用到的元素仅仅是栈底的**上一个没有被匹配的右括号的下标**。那么考虑能否把这个值存在一个变量中,这样可以省去栈 O(n) 的时间复杂度。利用两个计数器 left 和 right 。首先,从左到右遍历字符串,每当遇到 `'('`,增加 left 计数器,每当遇到 `')'` ,增加 right 计数器。每当 left 计数器与 right 计数器相等时,计算当前有效字符串的长度,并且记录目前为止找到的最长子字符串。当 right 计数器比 left 计数器大时,说明括号不匹配,于是将 left 和 right 计数器同时变回 0。这样的做法利用了贪心的思想考虑了以当前字符下标结尾的有效括号长度每次当右括号数量多于左括号数量的时候之前的字符就扔掉不再考虑重新从下一个字符开始计算。
- 但上面的做法会漏掉一种情况,就是遍历的时候左括号的数量始终大于右括号的数量,即 `(()` ,这种时候最长有效括号是求不出来的。解决办法是反向再计算一遍,如果从右往左计算,`(()` 先计算匹配的括号,最后只剩下 `'('`,这样依旧可以算出最长匹配的括号长度。反过来计算的方法和上述从左往右计算的方法一致:当 left 计数器比 right 计数器大时,将 left 和 right 计数器同时变回 0当 left 计数器与 right 计数器相等时,计算当前有效字符串的长度,并且记录目前为止找到的最长子字符串。这种方法的时间复杂度是 O(n),空间复杂度 O(1)。
## 代码
```go
package leetcode
// 解法一 栈
func longestValidParentheses(s string) int {
stack, res := []int{}, 0
stack = append(stack, -1)
for i := 0; i < len(s); i++ {
if s[i] == '(' {
stack = append(stack, i)
} else {
stack = stack[:len(stack)-1]
if len(stack) == 0 {
stack = append(stack, i)
} else {
res = max(res, i-stack[len(stack)-1])
}
}
}
return res
}
func max(a, b int) int {
if a > b {
return a
}
return b
}
// 解法二 双指针
func longestValidParentheses1(s string) int {
left, right, maxLength := 0, 0, 0
for i := 0; i < len(s); i++ {
if s[i] == '(' {
left++
} else {
right++
}
if left == right {
maxLength = max(maxLength, 2*right)
} else if right > left {
left, right = 0, 0
}
}
left, right = 0, 0
for i := len(s) - 1; i >= 0; i-- {
if s[i] == '(' {
left++
} else {
right++
}
if left == right {
maxLength = max(maxLength, 2*left)
} else if left > right {
left, right = 0, 0
}
}
return maxLength
}
```

View File

@ -0,0 +1,25 @@
package leetcode
func multiply(num1 string, num2 string) string {
if num1 == "0" || num2 == "0" {
return "0"
}
b1, b2, tmp := []byte(num1), []byte(num2), make([]int, len(num1)+len(num2))
for i := 0; i < len(b1); i++ {
for j := 0; j < len(b2); j++ {
tmp[i+j+1] += int(b1[i]-'0') * int(b2[j]-'0')
}
}
for i := len(tmp) - 1; i > 0; i-- {
tmp[i-1] += tmp[i] / 10
tmp[i] = tmp[i] % 10
}
if tmp[0] == 0 {
tmp = tmp[1:]
}
res := make([]byte, len(tmp))
for i := 0; i < len(tmp); i++ {
res[i] = '0' + byte(tmp[i])
}
return string(res)
}

View File

@ -0,0 +1,48 @@
package leetcode
import (
"fmt"
"testing"
)
type question43 struct {
para43
ans43
}
// para 是参数
// one 代表第一个参数
type para43 struct {
num1 string
num2 string
}
// ans 是答案
// one 代表第一个答案
type ans43 struct {
one string
}
func Test_Problem43(t *testing.T) {
qs := []question43{
{
para43{"2", "3"},
ans43{"6"},
},
{
para43{"123", "456"},
ans43{"56088"},
},
}
fmt.Printf("------------------------Leetcode Problem 43------------------------\n")
for _, q := range qs {
_, p := q.ans43, q.para43
fmt.Printf("【input】:%v 【output】:%v\n", p, multiply(p.num1, p.num2))
}
fmt.Printf("\n\n\n")
}

View File

@ -0,0 +1,66 @@
# [43. Multiply Strings](https://leetcode.com/problems/multiply-strings/)
## 题目
Given two non-negative integers `num1` and `num2` represented as strings, return the product of `num1` and `num2`, also represented as a string.
**Note:** You must not use any built-in BigInteger library or convert the inputs to integer directly.
**Example 1:**
```
Input: num1 = "2", num2 = "3"
Output: "6"
```
**Example 2:**
```
Input: num1 = "123", num2 = "456"
Output: "56088"
```
**Constraints:**
- `1 <= num1.length, num2.length <= 200`
- `num1` and `num2` consist of digits only.
- Both `num1` and `num2` do not contain any leading zero, except the number `0` itself.
## 题目大意
给定两个以字符串形式表示的非负整数 num1 和 num2返回 num1 和 num2 的乘积,它们的乘积也表示为字符串形式。
## 解题思路
- 用数组模拟乘法。创建一个数组长度为 `len(num1) + len(num2)` 的数组用于存储乘积。对于任意 `0 ≤ i < len(num1)``0 ≤ j < len(num2)``num1[i] * num2[j]` 的结果位于 `tmp[i+j+1]`,如果 `tmp[i+j+1]≥10`,则将进位部分加到 `tmp[i+j]`。最后,将数组 `tmp` 转成字符串,如果最高位是 0 则舍弃最高位。
## 代码
```go
package leetcode
func multiply(num1 string, num2 string) string {
if num1 == "0" || num2 == "0" {
return "0"
}
b1, b2, tmp := []byte(num1), []byte(num2), make([]int, len(num1)+len(num2))
for i := 0; i < len(b1); i++ {
for j := 0; j < len(b2); j++ {
tmp[i+j+1] += int(b1[i]-'0') * int(b2[j]-'0')
}
}
for i := len(tmp) - 1; i > 0; i-- {
tmp[i-1] += tmp[i] / 10
tmp[i] = tmp[i] % 10
}
if tmp[0] == 0 {
tmp = tmp[1:]
}
res := make([]byte, len(tmp))
for i := 0; i < len(tmp); i++ {
res[i] = '0' + byte(tmp[i])
}
return string(res)
}
```

View File

@ -0,0 +1,21 @@
package leetcode
func jump(nums []int) int {
if len(nums) == 1 {
return 0
}
needChoose, canReach, step := 0, 0, 0
for i, x := range nums {
if i+x > canReach {
canReach = i + x
if canReach >= len(nums)-1 {
return step + 1
}
}
if i == needChoose {
needChoose = canReach
step++
}
}
return step
}

View File

@ -0,0 +1,47 @@
package leetcode
import (
"fmt"
"testing"
)
type question45 struct {
para45
ans45
}
// para 是参数
// one 代表第一个参数
type para45 struct {
nums []int
}
// ans 是答案
// one 代表第一个答案
type ans45 struct {
one int
}
func Test_Problem45(t *testing.T) {
qs := []question45{
{
para45{[]int{2, 3, 1, 1, 4}},
ans45{2},
},
{
para45{[]int{2, 3, 0, 1, 4}},
ans45{2},
},
}
fmt.Printf("------------------------Leetcode Problem 45------------------------\n")
for _, q := range qs {
_, p := q.ans45, q.para45
fmt.Printf("【input】:%v 【output】:%v\n", p, jump(p.nums))
}
fmt.Printf("\n\n\n")
}

View File

@ -0,0 +1,67 @@
# [45. Jump Game II](https://leetcode.com/problems/jump-game-ii/)
## 题目
Given an array of non-negative integers `nums`, you are initially positioned at the first index of the array.
Each element in the array represents your maximum jump length at that position.
Your goal is to reach the last index in the minimum number of jumps.
You can assume that you can always reach the last index.
**Example 1:**
```
Input: nums = [2,3,1,1,4]
Output: 2
Explanation: The minimum number of jumps to reach the last index is 2. Jump 1 step from index 0 to 1, then 3 steps to the last index.
```
**Example 2:**
```
Input: nums = [2,3,0,1,4]
Output: 2
```
**Constraints:**
- `1 <= nums.length <= 1000`
- `0 <= nums[i] <= 10^5`
## 题目大意
给定一个非负整数数组,你最初位于数组的第一个位置。数组中的每个元素代表你在该位置可以跳跃的最大长度。你的目标是使用最少的跳跃次数到达数组的最后一个位置。
## 解题思路
- 要求找到最少跳跃次数,顺理成章的会想到用贪心算法解题。扫描步数数组,维护当前能够到达最大下标的位置,记为能到达的最远边界,如果扫描过程中到达了最远边界,更新边界并将跳跃次数 + 1。
- 扫描数组的时候,其实不需要扫描最后一个元素,因为在跳到最后一个元素之前,能到达的最远边界一定大于等于最后一个元素的位置,不然就跳不到最后一个元素,到达不了终点了;如果遍历到最后一个元素,说明边界正好为最后一个位置,最终跳跃次数直接 + 1 即可,也不需要访问最后一个元素。
## 代码
```go
package leetcode
func jump(nums []int) int {
if len(nums) == 1 {
return 0
}
needChoose, canReach, step := 0, 0, 0
for i, x := range nums {
if i+x > canReach {
canReach = i + x
if canReach >= len(nums)-1 {
return step + 1
}
}
if i == needChoose {
needChoose = canReach
step++
}
}
return step
}
```

View File

@ -1,26 +1,17 @@
package leetcode
func rotate(matrix [][]int) {
row := len(matrix)
if row <= 0 {
return
}
column := len(matrix[0])
length := len(matrix)
// rotate by diagonal 对角线变换
for i := 0; i < row; i++ {
for j := i + 1; j < column; j++ {
tmp := matrix[i][j]
matrix[i][j] = matrix[j][i]
matrix[j][i] = tmp
for i := 0; i < length; i++ {
for j := i + 1; j < length; j++ {
matrix[i][j], matrix[j][i] = matrix[j][i], matrix[i][j]
}
}
// rotate by vertical centerline 竖直轴对称翻转
halfColumn := column / 2
for i := 0; i < row; i++ {
for j := 0; j < halfColumn; j++ {
tmp := matrix[i][j]
matrix[i][j] = matrix[i][column-j-1]
matrix[i][column-j-1] = tmp
for i := 0; i < length; i++ {
for j := 0; j < length/2; j++ {
matrix[i][j], matrix[i][length-j-1] = matrix[i][length-j-1], matrix[i][j]
}
}
}

View File

@ -10,8 +10,9 @@ Rotate the image by 90 degrees (clockwise).
You have to rotate the image **[in-place](https://en.wikipedia.org/wiki/In-place_algorithm)**, which means you have to modify the input 2D matrix directly. **DO NOT** allocate another 2D matrix and do the rotation.
**Example 1:**
**Example 1**:
![](https://assets.leetcode.com/uploads/2020/08/28/mat1.jpg)
Given input matrix =
[
@ -28,8 +29,9 @@ You have to rotate the image **[in-place](https://en.wikipedia.org/wiki/In-plac
]
**Example 2:**
**Example 2**:
![](https://assets.leetcode.com/uploads/2020/08/28/mat2.jpg)
Given input matrix =
[

View File

@ -47,39 +47,45 @@ func generateBoard(n int, row *[]int) []string {
return board
}
// 解法二 二进制操作法
// class Solution
// {
// int n;
// string getNq(int p)
// {
// string s(n, '.');
// s[p] = 'Q';
// return s;
// }
// void nQueens(int p, int l, int m, int r, vector<vector<string>> &res)
// {
// static vector<string> ans;
// if (p >= n)
// {
// res.push_back(ans);
// return ;
// }
// int mask = l | m | r;
// for (int i = 0, b = 1; i < n; ++ i, b <<= 1)
// if (!(mask & b))
// {
// ans.push_back(getNq(i));
// nQueens(p + 1, (l | b) >> 1, m | b, (r | b) << 1, res);
// ans.pop_back();
// }
// }
// public:
// vector<vector<string> > solveNQueens(int n)
// {
// this->n = n;
// vector<vector<string>> res;
// nQueens(0, 0, 0, 0, res);
// return res;
// }
// };
// 解法二 二进制操作法 Signed-off-by: Hanlin Shi shihanlin9@gmail.com
func solveNQueens2(n int) (res [][]string) {
placements := make([]string, n)
for i := range placements {
buf := make([]byte, n)
for j := range placements {
if i == j {
buf[j] = 'Q'
} else {
buf[j] = '.'
}
}
placements[i] = string(buf)
}
var construct func(prev []int)
construct = func(prev []int) {
if len(prev) == n {
plan := make([]string, n)
for i := 0; i < n; i++ {
plan[i] = placements[prev[i]]
}
res = append(res, plan)
return
}
occupied := 0
for i := range prev {
dist := len(prev) - i
bit := 1 << prev[i]
occupied |= bit | bit<<dist | bit>>dist
}
prev = append(prev, -1)
for i := 0; i < n; i++ {
if (occupied>>i)&1 != 0 {
continue
}
prev[len(prev)-1] = i
construct(prev)
}
}
construct(make([]int, 0, n))
return
}

View File

@ -40,4 +40,5 @@ Each solution contains a distinct board configuration of the *n*-queens' placem
- 利用 col 数组记录列信息col 有 `n` 列。用 dia1dia2 记录从左下到右上的对角线从左上到右下的对角线的信息dia1 和 dia2 分别都有 `2*n-1` 个。
- dia1 对角线的规律是 `i + j 是定值`,例如[0,0],为 0[1,0]、[0,1] 为 1[2,0]、[1,1]、[0,2] 为 2
- dia2 对角线的规律是 `i - j 是定值`,例如[0,7],为 -7[0,6]、[1,7] 为 -6[0,5]、[1,6]、[2,7] 为 -5为了使他们从 0 开始i - j + n - 1 偏移到 0 开始,所以 dia2 的规律是 `i - j + n - 1 为定值`
- 还有一个位运算的方法,每行只能选一个位置放皇后,那么对每行遍历可能放皇后的位置。如何高效判断哪些点不能放皇后呢?这里的做法毕竟巧妙,把所有之前选过的点按照顺序存下来,然后根据之前选的点到当前行的距离,就可以快速判断是不是会有冲突。举个例子: 假如在 4 皇后问题中,如果第一二行已经选择了位置 [1, 3],那么在第三行选择时,首先不能再选 1, 3 列了,而对于第三行, 1 距离长度为2所以它会影响到 -1, 3 两个列。同理3 在第二行,距离第三行为 1所以 3 会影响到列 2, 4。由上面的结果我们知道 -1, 4 超出边界了不用去管,别的不能选的点是 1, 2, 3所以第三行就只能选 0。在代码实现中可以在每次遍历前根据之前选择的情况生成一个 occupied 用来记录当前这一行,已经被选了的和由于之前皇后攻击范围所以不能选的位置,然后只选择合法的位置进入到下一层递归。另外就是预处理了一个皇后放不同位置的字符串,这样这些字符串在返回结果的时候是可以在内存中复用的,省一点内存。

View File

@ -0,0 +1,16 @@
package leetcode
func lengthOfLastWord(s string) int {
last := len(s) - 1
for last >= 0 && s[last] == ' ' {
last--
}
if last < 0 {
return 0
}
first := last
for first >= 0 && s[first] != ' ' {
first--
}
return last - first
}

View File

@ -0,0 +1,50 @@
package leetcode
import (
"fmt"
"testing"
)
type question58 struct {
para58
ans58
}
// para 是参数
type para58 struct {
s string
}
// ans 是答案
type ans58 struct {
ans int
}
func Test_Problem58(t *testing.T) {
qs := []question58{
{
para58{"Hello World"},
ans58{5},
},
{
para58{" fly me to the moon "},
ans58{4},
},
{
para58{"luffy is still joyboy"},
ans58{6},
},
}
fmt.Printf("------------------------Leetcode Problem 58------------------------\n")
for _, q := range qs {
_, p := q.ans58, q.para58
fmt.Printf("【input】:%v 【output】:%v\n", p, lengthOfLastWord(p.s))
}
fmt.Printf("\n\n\n")
}

View File

@ -0,0 +1,70 @@
# [58. Length of Last Word](https://leetcode.com/problems/length-of-last-word/)
## 题目
Given a string `s` consisting of some words separated by some number of spaces, return *the length of the **last** word in the string.*
A **word** is a maximal substring consisting of non-space characters only.
**Example 1:**
```
Input: s = "Hello World"
Output: 5
Explanation: The last word is "World" with length 5.
```
**Example 2:**
```
Input: s = " fly me to the moon "
Output: 4
Explanation: The last word is "moon" with length 4.
```
**Example 3:**
```
Input: s = "luffy is still joyboy"
Output: 6
Explanation: The last word is "joyboy" with length 6.
```
**Constraints:**
- `1 <= s.length <= 104`
- `s` consists of only English letters and spaces `' '`.
- There will be at least one word in `s`.
## 题目大意
给你一个字符串 `s`,由若干单词组成,单词前后用一些空格字符隔开。返回字符串中最后一个单词的长度。**单词** 是指仅由字母组成、不包含任何空格字符的最大子字符串。
## 解题思路
- 先从后过滤掉空格找到单词尾部,再从尾部向前遍历,找到单词头部,最后两者相减,即为单词的长度。
## 代码
```go
package leetcode
func lengthOfLastWord(s string) int {
last := len(s) - 1
for last >= 0 && s[last] == ' ' {
last--
}
if last < 0 {
return 0
}
first := last
for first >= 0 && s[first] != ' ' {
first--
}
return last - first
}
```

View File

@ -5,14 +5,12 @@ func uniquePaths(m int, n int) int {
for i := 0; i < n; i++ {
dp[i] = make([]int, m)
}
for i := 0; i < m; i++ {
dp[0][i] = 1
}
for i := 0; i < n; i++ {
dp[i][0] = 1
}
for i := 1; i < n; i++ {
for j := 1; j < m; j++ {
for j := 0; j < m; j++ {
if i == 0 || j == 0 {
dp[i][j] = 1
continue
}
dp[i][j] = dp[i-1][j] + dp[i][j-1]
}
}

View File

@ -0,0 +1,22 @@
package leetcode
func isNumber(s string) bool {
numFlag, dotFlag, eFlag := false, false, false
for i := 0; i < len(s); i++ {
if '0' <= s[i] && s[i] <= '9' {
numFlag = true
} else if s[i] == '.' && !dotFlag && !eFlag {
dotFlag = true
} else if (s[i] == 'e' || s[i] == 'E') && !eFlag && numFlag {
eFlag = true
numFlag = false // reJudge integer after 'e' or 'E'
} else if (s[i] == '+' || s[i] == '-') && (i == 0 || s[i-1] == 'e' || s[i-1] == 'E') {
continue
} else {
return false
}
}
// avoid case: s == '.' or 'e/E' or '+/-' and etc...
// string s must have num
return numFlag
}

View File

@ -0,0 +1,41 @@
package leetcode
import (
"fmt"
"testing"
)
func Test_Problem65(t *testing.T) {
tcs := []struct {
s string
ans bool
}{
{
"0",
true,
},
{
"e",
false,
},
{
".",
false,
},
{
".1",
true,
},
}
fmt.Printf("------------------------Leetcode Problem 65------------------------\n")
for _, tc := range tcs {
fmt.Printf("【input】:%v 【output】:%v\n", tc, isNumber(tc.s))
}
fmt.Printf("\n\n\n")
}

View File

@ -0,0 +1,78 @@
# [65. Valid Number](https://leetcode.com/problems/valid-number/)
## 题目
A **valid number** can be split up into these components (in order):
1. A **decimal number** or an integer.
2. (Optional) An 'e' or 'E', followed by an **integer.**
A **decimal number** can be split up into these components (in order):
1. (Optional) A sign character (either '+' or '-').
2. One of the following formats:
1. One or more digits, followed by a dot '.'.
2. One or more digits, followed by a dot '.', followed by one or more digits.
3. A dot '.', followed by one or more digits.
An **integer** can be split up into these components (in order):
1. (Optional) A sign character (either '+' or '-').
2. One or more digits.
For example, all the following are valid numbers: `["2", "0089", "-0.1", "+3.14", "4.", "-.9", "2e10", "-90E3", "3e+7", "+6e-1", "53.5e93", "-123.456e789"]`, while the following are not valid numbers: `["abc", "1a", "1e", "e3", "99e2.5", "--6", "-+3", "95a54e53"].`
Given a string s, return true if s is a **valid number.**
**Example:**
Input: s = "0"
Output: true
Input: s = "e"
Output: false
## 题目大意
给定一个字符串S请根据以上的规则判断该字符串是否是一个有效的数字字符串。
## 解题思路
- 用三个变量分别标记是否出现过数字、是否出现过'.'和 是否出现过 'e/E'
- 从左到右依次遍历字符串中的每一个元素
- 如果是数字,则标记数字出现过
- 如果是 '.', 则需要 '.'没有出现过,并且 'e/E' 没有出现过,才会进行标记
- 如果是 'e/E', 则需要 'e/E'没有出现过,并且前面出现过数字,才会进行标记
- 如果是 '+/-', 则需要是第一个字符,或者前一个字符是 'e/E',才会进行标记,并重置数字出现的标识
- 最后返回时需要字符串中至少出现过数字避免下列case: s == '.' or 'e/E' or '+/e' and etc...
## 代码
```go
package leetcode
func isNumber(s string) bool {
numFlag, dotFlag, eFlag := false, false, false
for i := 0; i < len(s); i++ {
if '0' <= s[i] && s[i] <= '9' {
numFlag = true
} else if s[i] == '.' && !dotFlag && !eFlag {
dotFlag = true
} else if (s[i] == 'e' || s[i] == 'E') && !eFlag && numFlag {
eFlag = true
numFlag = false // reJudge integer after 'e' or 'E'
} else if (s[i] == '+' || s[i] == '-') && (i == 0 || s[i-1] == 'e' || s[i-1] == 'E') {
continue
} else {
return false
}
}
// avoid case: s == '.' or 'e/E' or '+/-' and etc...
// string s must have num
return numFlag
}
```

View File

@ -1,21 +1,17 @@
package leetcode
func plusOne(digits []int) []int {
if len(digits) == 0 {
return []int{}
}
carry := 1
for i := len(digits) - 1; i >= 0; i-- {
if digits[i]+carry > 9 {
digits[i] = 0
carry = 1
} else {
digits[i] += carry
carry = 0
digits[i]++
if digits[i] != 10 {
// no carry
return digits
}
// carry
digits[i] = 0
}
if digits[0] == 0 && carry == 1 {
digits = append([]int{1}, digits...)
}
// all carry
digits[0] = 1
digits = append(digits, 0)
return digits
}

View File

@ -1,23 +1,17 @@
package leetcode
// 解法一 二分
// 解法一 二分, 找到最后一个满足 n^2 <= x 的整数n
func mySqrt(x int) int {
if x == 0 {
return 0
}
left, right, res := 1, x, 0
for left <= right {
mid := left + ((right - left) >> 1)
if mid < x/mid {
left = mid + 1
res = mid
} else if mid == x/mid {
return mid
l, r := 0, x
for l < r {
mid := (l + r + 1) / 2
if mid*mid > x {
r = mid - 1
} else {
right = mid - 1
l = mid
}
}
return res
return l
}
// 解法二 牛顿迭代法 https://en.wikipedia.org/wiki/Integer_square_root

View File

@ -0,0 +1,54 @@
package leetcode
func setZeroes(matrix [][]int) {
if len(matrix) == 0 || len(matrix[0]) == 0 {
return
}
isFirstRowExistZero, isFirstColExistZero := false, false
for i := 0; i < len(matrix); i++ {
if matrix[i][0] == 0 {
isFirstColExistZero = true
break
}
}
for j := 0; j < len(matrix[0]); j++ {
if matrix[0][j] == 0 {
isFirstRowExistZero = true
break
}
}
for i := 1; i < len(matrix); i++ {
for j := 1; j < len(matrix[0]); j++ {
if matrix[i][j] == 0 {
matrix[i][0] = 0
matrix[0][j] = 0
}
}
}
// 处理[1:]行全部置 0
for i := 1; i < len(matrix); i++ {
if matrix[i][0] == 0 {
for j := 1; j < len(matrix[0]); j++ {
matrix[i][j] = 0
}
}
}
// 处理[1:]列全部置 0
for j := 1; j < len(matrix[0]); j++ {
if matrix[0][j] == 0 {
for i := 1; i < len(matrix); i++ {
matrix[i][j] = 0
}
}
}
if isFirstRowExistZero {
for j := 0; j < len(matrix[0]); j++ {
matrix[0][j] = 0
}
}
if isFirstColExistZero {
for i := 0; i < len(matrix); i++ {
matrix[i][0] = 0
}
}
}

View File

@ -0,0 +1,47 @@
package leetcode
import (
"fmt"
"testing"
)
type question73 struct {
para73
ans73
}
// para 是参数
// one 代表第一个参数
type para73 struct {
matrix [][]int
}
// ans 是答案
// one 代表第一个答案
type ans73 struct {
}
func Test_Problem73(t *testing.T) {
qs := []question73{
{
para73{[][]int{
{0, 1, 2, 0},
{3, 4, 5, 2},
{1, 3, 1, 5},
}},
ans73{},
},
}
fmt.Printf("------------------------Leetcode Problem 73------------------------\n")
for _, q := range qs {
_, p := q.ans73, q.para73
fmt.Printf("【input】:%v ", p)
setZeroes(p.matrix)
fmt.Printf("【output】:%v\n", p)
}
fmt.Printf("\n\n\n")
}

View File

@ -0,0 +1,104 @@
# [73. Set Matrix Zeroes](https://leetcode.com/problems/set-matrix-zeroes/)
## 题目
Given an *`m* x *n*` matrix. If an element is **0**, set its entire row and column to **0**. Do it **[in-place](https://en.wikipedia.org/wiki/In-place_algorithm)**.
**Follow up:**
- A straight forward solution using O(*mn*) space is probably a bad idea.
- A simple improvement uses O(*m* + *n*) space, but still not the best solution.
- Could you devise a constant space solution?
**Example 1:**
![https://assets.leetcode.com/uploads/2020/08/17/mat1.jpg](https://assets.leetcode.com/uploads/2020/08/17/mat1.jpg)
```
Input: matrix = [[1,1,1],[1,0,1],[1,1,1]]
Output: [[1,0,1],[0,0,0],[1,0,1]]
```
**Example 2:**
![https://assets.leetcode.com/uploads/2020/08/17/mat2.jpg](https://assets.leetcode.com/uploads/2020/08/17/mat2.jpg)
```
Input: matrix = [[0,1,2,0],[3,4,5,2],[1,3,1,5]]
Output: [[0,0,0,0],[0,4,5,0],[0,3,1,0]]
```
**Constraints:**
- `m == matrix.length`
- `n == matrix[0].length`
- `1 <= m, n <= 200`
- `2^31 <= matrix[i][j] <= 2^31 - 1`
## 题目大意
给定一个 `m x n` 的矩阵,如果一个元素为 0则将其所在行和列的所有元素都设为 0。请使用原地算法。
## 解题思路
- 此题考查对程序的控制能力,无算法思想。题目要求采用原地的算法,所有修改即在原二维数组上进行。在二维数组中有 2 个特殊位置,一个是第一行,一个是第一列。它们的特殊性在于,它们之间只要有一个 0它们都会变为全 0 。先用 2 个变量记录这一行和这一列中是否有 0防止之后的修改覆盖了这 2 个地方。然后除去这一行和这一列以外的部分判断是否有 0如果有 0将它们所在的行第一个元素标记为 0所在列的第一个元素标记为 0 。最后通过标记,将对应的行列置 0 即可。
## 代码
```go
package leetcode
func setZeroes(matrix [][]int) {
if len(matrix) == 0 || len(matrix[0]) == 0 {
return
}
isFirstRowExistZero, isFirstColExistZero := false, false
for i := 0; i < len(matrix); i++ {
if matrix[i][0] == 0 {
isFirstColExistZero = true
break
}
}
for j := 0; j < len(matrix[0]); j++ {
if matrix[0][j] == 0 {
isFirstRowExistZero = true
break
}
}
for i := 1; i < len(matrix); i++ {
for j := 1; j < len(matrix[0]); j++ {
if matrix[i][j] == 0 {
matrix[i][0] = 0
matrix[0][j] = 0
}
}
}
// 处理[1:]行全部置 0
for i := 1; i < len(matrix); i++ {
if matrix[i][0] == 0 {
for j := 1; j < len(matrix[0]); j++ {
matrix[i][j] = 0
}
}
}
// 处理[1:]列全部置 0
for j := 1; j < len(matrix[0]); j++ {
if matrix[0][j] == 0 {
for i := 1; i < len(matrix); i++ {
matrix[i][j] = 0
}
}
}
if isFirstRowExistZero {
for j := 0; j < len(matrix[0]); j++ {
matrix[0][j] = 0
}
}
if isFirstColExistZero {
for i := 0; i < len(matrix); i++ {
matrix[i][0] = 0
}
}
}
```

View File

@ -1,28 +1,16 @@
package leetcode
func sortColors(nums []int) {
if len(nums) == 0 {
return
}
r := 0
w := 0
b := 0 // label the end of different colors;
for _, num := range nums {
if num == 0 {
nums[b] = 2
b++
nums[w] = 1
w++
nums[r] = 0
r++
} else if num == 1 {
nums[b] = 2
b++
nums[w] = 1
w++
} else if num == 2 {
b++
zero, one := 0, 0
for i, n := range nums {
nums[i] = 2
if n <= 1 {
nums[one] = 1
one++
}
if n == 0 {
nums[zero] = 0
zero++
}
}
}

View File

@ -32,9 +32,7 @@ func minWindow(s string, t string) string {
}
}
if finalLeft != -1 {
for i := finalLeft; i < finalRight+1; i++ {
result += string(s[i])
}
result = string(s[finalLeft : finalRight+1])
}
return result
}

View File

@ -1,35 +1,12 @@
package leetcode
func removeDuplicates80(nums []int) int {
if len(nums) == 0 {
return 0
}
last, finder := 0, 0
for last < len(nums)-1 {
startFinder := -1
for nums[finder] == nums[last] {
if startFinder == -1 || startFinder > finder {
startFinder = finder
}
if finder == len(nums)-1 {
break
}
finder++
}
if finder-startFinder >= 2 && nums[finder-1] == nums[last] && nums[finder] != nums[last] {
nums[last+1] = nums[finder-1]
nums[last+2] = nums[finder]
last += 2
} else {
nums[last+1] = nums[finder]
last++
}
if finder == len(nums)-1 {
if nums[finder] != nums[last-1] {
nums[last] = nums[finder]
}
return last + 1
func removeDuplicates(nums []int) int {
slow := 0
for fast, v := range nums {
if fast < 2 || nums[slow-2] != v {
nums[slow] = v
slow++
}
}
return last + 1
return slow
}

View File

@ -61,7 +61,7 @@ func Test_Problem80(t *testing.T) {
for _, q := range qs {
_, p := q.ans80, q.para80
fmt.Printf("【input】:%v 【output】:%v\n", p.one, removeDuplicates80(p.one))
fmt.Printf("【input】:%v 【output】:%v\n", p.one, removeDuplicates(p.one))
}
fmt.Printf("\n\n\n")
}

View File

@ -51,6 +51,6 @@ for (int i = 0; i < len; i++) {
## 解题思路
这道题和第 26 题很像。是第 26 题的加强版。这道题和第 283 题,第 27 题基本一致283 题是删除 027 题是删除指定元素,这一题是删除重复元素,实质是一样的
这里数组的删除并不是真的删除只是将删除的元素移动到数组后面的空间内然后返回数组实际剩余的元素个数OJ 最终判断题目的时候会读取数组剩余个数的元素进行输出
- 问题提示有序数组,一般最容易想到使用双指针的解法,双指针的关键点:移动两个指针的条件
- 在该题中移动的条件:快指针从头遍历数组,慢指针指向修改后的数组的末端,当慢指针指向倒数第二个数与快指针指向的数不相等时,才移动慢指针,同时赋值慢指针。
- 处理边界条件:当数组小于两个元素时,不做处理

View File

@ -1,32 +1,25 @@
package leetcode
import "fmt"
func largestRectangleArea(heights []int) int {
maxArea, stack, height := 0, []int{}, 0
for i := 0; i <= len(heights); i++ {
if i == len(heights) {
height = 0
} else {
height = heights[i]
maxArea := 0
n := len(heights) + 2
// Add a sentry at the beginning and the end
getHeight := func(i int) int {
if i == 0 || n-1 == i {
return 0
}
if len(stack) == 0 || height >= heights[stack[len(stack)-1]] {
stack = append(stack, i)
} else {
tmp := stack[len(stack)-1]
fmt.Printf("1. tmp = %v stack = %v\n", tmp, stack)
stack = stack[:len(stack)-1]
length := 0
if len(stack) == 0 {
length = i
} else {
length = i - 1 - stack[len(stack)-1]
fmt.Printf("2. length = %v stack = %v i = %v\n", length, stack, i)
}
maxArea = max(maxArea, heights[tmp]*length)
fmt.Printf("3. maxArea = %v heights[tmp]*length = %v\n", maxArea, heights[tmp]*length)
i--
return heights[i-1]
}
st := make([]int, 0, n/2)
for i := 0; i < n; i++ {
for len(st) > 0 && getHeight(st[len(st)-1]) > getHeight(i) {
// pop stack
idx := st[len(st)-1]
st = st[:len(st)-1]
maxArea = max(maxArea, getHeight(idx)*(i-st[len(st)-1]-1))
}
// push stack
st = append(st, i)
}
return maxArea
}

View File

@ -40,6 +40,10 @@ func Test_Problem84(t *testing.T) {
para84{[]int{1, 1}},
ans84{2},
},
{
para84{[]int{2, 1, 2}},
ans84{3},
},
}
fmt.Printf("------------------------Leetcode Problem 84------------------------\n")

View File

@ -1,29 +1,16 @@
package leetcode
func merge(nums1 []int, m int, nums2 []int, n int) {
if m == 0 {
copy(nums1, nums2)
return
}
// 这里不需要,因为测试数据考虑到了第一个数组的空间问题
// for index := 0; index < n; index++ {
// nums1 = append(nums1, nums2[index])
// }
i := m - 1
j := n - 1
k := m + n - 1
// 从后面往前放,只需要循环一次即可
for ; i >= 0 && j >= 0; k-- {
if nums1[i] > nums2[j] {
nums1[k] = nums1[i]
i--
for p := m + n; m > 0 && n > 0; p-- {
if nums1[m-1] <= nums2[n-1] {
nums1[p-1] = nums2[n-1]
n--
} else {
nums1[k] = nums2[j]
j--
nums1[p-1] = nums1[m-1]
m--
}
}
for ; j >= 0; k-- {
nums1[k] = nums2[j]
j--
for ; n > 0; n-- {
nums1[n-1] = nums2[n-1]
}
}

View File

@ -29,20 +29,10 @@ func Test_Problem88(t *testing.T) {
qs := []question88{
// question{
// para{[]int{0}, 0, []int{1}, 1},
// ans{[]int{1}},
// },
//
// question{
// para{[]int{1, 3, 5, 7}, 4, []int{2, 4}, 2},
// ans{[]int{1, 2, 3, 4}},
// },
//
// question{
// para{[]int{1, 3, 5, 7}, 4, []int{2, 2}, 2},
// ans{[]int{1, 2, 2, 3}},
// },
{
para88{[]int{0}, 0, []int{1}, 1},
ans88{[]int{1}},
},
{
para88{[]int{1, 2, 3, 0, 0, 0}, 3, []int{2, 5, 6}, 3},

View File

@ -1,29 +1,16 @@
package leetcode
import (
"strconv"
)
func numDecodings(s string) int {
if len(s) == 0 {
return 0
}
dp := make([]int, len(s)+1)
n := len(s)
dp := make([]int, n+1)
dp[0] = 1
if s[:1] == "0" {
dp[1] = 0
} else {
dp[1] = 1
}
for i := 2; i <= len(s); i++ {
lastNum, _ := strconv.Atoi(s[i-1 : i])
if lastNum >= 1 && lastNum <= 9 {
for i := 1; i <= n; i++ {
if s[i-1] != '0' {
dp[i] += dp[i-1]
}
lastNum, _ = strconv.Atoi(s[i-2 : i])
if lastNum >= 10 && lastNum <= 26 {
if i > 1 && s[i-2] != '0' && (s[i-2]-'0')*10+(s[i-1]-'0') <= 26 {
dp[i] += dp[i-2]
}
}
return dp[len(s)]
return dp[n]
}

View File

@ -0,0 +1,35 @@
package leetcode
func isInterleave(s1 string, s2 string, s3 string) bool {
if len(s1)+len(s2) != len(s3) {
return false
}
visited := make(map[int]bool)
return dfs(s1, s2, s3, 0, 0, visited)
}
func dfs(s1, s2, s3 string, p1, p2 int, visited map[int]bool) bool {
if p1+p2 == len(s3) {
return true
}
if _, ok := visited[(p1*len(s3))+p2]; ok {
return false
}
visited[(p1*len(s3))+p2] = true
var match1, match2 bool
if p1 < len(s1) && s3[p1+p2] == s1[p1] {
match1 = true
}
if p2 < len(s2) && s3[p1+p2] == s2[p2] {
match2 = true
}
if match1 && match2 {
return dfs(s1, s2, s3, p1+1, p2, visited) || dfs(s1, s2, s3, p1, p2+1, visited)
} else if match1 {
return dfs(s1, s2, s3, p1+1, p2, visited)
} else if match2 {
return dfs(s1, s2, s3, p1, p2+1, visited)
} else {
return false
}
}

View File

@ -0,0 +1,54 @@
package leetcode
import (
"fmt"
"testing"
)
type question97 struct {
para97
ans97
}
// para 是参数
// one 代表第一个参数
type para97 struct {
s1 string
s2 string
s3 string
}
// ans 是答案
// one 代表第一个答案
type ans97 struct {
one bool
}
func Test_Problem97(t *testing.T) {
qs := []question97{
{
para97{"aabcc", "dbbca", "aadbbcbcac"},
ans97{true},
},
{
para97{"aabcc", "dbbca", "aadbbbaccc"},
ans97{false},
},
{
para97{"", "", ""},
ans97{true},
},
}
fmt.Printf("------------------------Leetcode Problem 97------------------------\n")
for _, q := range qs {
_, p := q.ans97, q.para97
fmt.Printf("【input】:%v 【output】:%v\n", p, isInterleave(p.s1, p.s2, p.s3))
}
fmt.Printf("\n\n\n")
}

View File

@ -0,0 +1,104 @@
# [97. Interleaving String](https://leetcode.com/problems/interleaving-string/)
## 题目
Given strings `s1`, `s2`, and `s3`, find whether `s3` is formed by an **interleaving** of `s1` and `s2`.
An **interleaving** of two strings `s` and `t` is a configuration where they are divided into **non-empty** substrings such that:
- `s = s1 + s2 + ... + sn`
- `t = t1 + t2 + ... + tm`
- `|n - m| <= 1`
- The **interleaving** is `s1 + t1 + s2 + t2 + s3 + t3 + ...` or `t1 + s1 + t2 + s2 + t3 + s3 + ...`
**Note:** `a + b` is the concatenation of strings `a` and `b`.
**Example 1:**
![https://assets.leetcode.com/uploads/2020/09/02/interleave.jpg](https://assets.leetcode.com/uploads/2020/09/02/interleave.jpg)
```
Input: s1 = "aabcc", s2 = "dbbca", s3 = "aadbbcbcac"
Output: true
```
**Example 2:**
```
Input: s1 = "aabcc", s2 = "dbbca", s3 = "aadbbbaccc"
Output: false
```
**Example 3:**
```
Input: s1 = "", s2 = "", s3 = ""
Output: true
```
**Constraints:**
- `0 <= s1.length, s2.length <= 100`
- `0 <= s3.length <= 200`
- `s1`, `s2`, and `s3` consist of lowercase English letters.
**Follow up:** Could you solve it using only `O(s2.length)` additional memory space?
## 题目大意
给定三个字符串 s1、s2、s3请你帮忙验证 s3 是否是由 s1  s2 交错 组成的。两个字符串 s 和 t 交错 的定义与过程如下,其中每个字符串都会被分割成若干 非空 子字符串:
- s = s1 + s2 + ... + sn
- t = t1 + t2 + ... + tm
- |n - m| <= 1
- 交错 是 s1 + t1 + s2 + t2 + s3 + t3 + ... 或者 t1 + s1 + t2 + s2 + t3 + s3 + ...
提示a + b 意味着字符串 a 和 b 连接。
## 解题思路
- 深搜或者广搜暴力解题。笔者用深搜实现的。记录 s1 和 s2 串当前比较的位置 p1 和 p2。如果 s3[p1+p2] 的位置上等于 s1[p1] 或者 s2[p2] 代表能匹配上,那么继续往后移动 p1 和 p2 相应的位置。因为是交错字符串,所以判断匹配的位置是 s3[p1+p2] 的位置。如果仅仅这么写会超时s1 和 s2 两个字符串重复交叉判断的位置太多了。需要加上记忆化搜索。可以用 visited[i][j] 这样的二维数组来记录是否搜索过了。笔者为了压缩空间,将 i 和 j 编码压缩到一维数组了。i * len(s3) + j 是唯一下标,所以可以用这种方式存储是否搜索过。具体代码见下面的实现。
## 代码
```go
package leetcode
func isInterleave(s1 string, s2 string, s3 string) bool {
if len(s1)+len(s2) != len(s3) {
return false
}
visited := make(map[int]bool)
return dfs(s1, s2, s3, 0, 0, visited)
}
func dfs(s1, s2, s3 string, p1, p2 int, visited map[int]bool) bool {
if p1+p2 == len(s3) {
return true
}
if _, ok := visited[(p1*len(s3))+p2]; ok {
return false
}
visited[(p1*len(s3))+p2] = true
var match1, match2 bool
if p1 < len(s1) && s3[p1+p2] == s1[p1] {
match1 = true
}
if p2 < len(s2) && s3[p1+p2] == s2[p2] {
match2 = true
}
if match1 && match2 {
return dfs(s1, s2, s3, p1+1, p2, visited) || dfs(s1, s2, s3, p1, p2+1, visited)
} else if match1 {
return dfs(s1, s2, s3, p1+1, p2, visited)
} else if match2 {
return dfs(s1, s2, s3, p1, p2+1, visited)
} else {
return false
}
}
```

View File

@ -16,7 +16,26 @@ type TreeNode = structures.TreeNode
* }
*/
// 解法一 dfs
func isSymmetric(root *TreeNode) bool {
if root == nil {
return true
}
return isMirror(root.Left, root.Right)
}
func isMirror(left *TreeNode, right *TreeNode) bool {
if left == nil && right == nil {
return true
}
if left == nil || right == nil {
return false
}
return (left.Val == right.Val) && isMirror(left.Left, right.Right) && isMirror(left.Right, right.Left)
}
// 解法二
func isSymmetric1(root *TreeNode) bool {
if root == nil {
return true
}

View File

@ -21,50 +21,42 @@ func levelOrder(root *TreeNode) [][]int {
if root == nil {
return [][]int{}
}
queue := []*TreeNode{}
queue = append(queue, root)
curNum, nextLevelNum, res, tmp := 1, 0, [][]int{}, []int{}
for len(queue) != 0 {
if curNum > 0 {
node := queue[0]
if node.Left != nil {
queue = append(queue, node.Left)
nextLevelNum++
queue := []*TreeNode{root}
res := make([][]int, 0)
for len(queue) > 0 {
l := len(queue)
tmp := make([]int, 0, l)
for i := 0; i < l; i++ {
if queue[i].Left != nil {
queue = append(queue, queue[i].Left)
}
if node.Right != nil {
queue = append(queue, node.Right)
nextLevelNum++
if queue[i].Right != nil {
queue = append(queue, queue[i].Right)
}
curNum--
tmp = append(tmp, node.Val)
queue = queue[1:]
}
if curNum == 0 {
res = append(res, tmp)
curNum = nextLevelNum
nextLevelNum = 0
tmp = []int{}
tmp = append(tmp, queue[i].Val)
}
queue = queue[l:]
res = append(res, tmp)
}
return res
}
// 解法二 DFS
func levelOrder1(root *TreeNode) [][]int {
levels := [][]int{}
dfsLevel(root, -1, &levels)
return levels
}
func dfsLevel(node *TreeNode, level int, res *[][]int) {
if node == nil {
return
var res [][]int
var dfsLevel func(node *TreeNode, level int)
dfsLevel = func(node *TreeNode, level int) {
if node == nil {
return
}
if len(res) == level {
res = append(res, []int{node.Val})
} else {
res[level] = append(res[level], node.Val)
}
dfsLevel(node.Left, level+1)
dfsLevel(node.Right, level+1)
}
currLevel := level + 1
for len(*res) <= currLevel {
*res = append(*res, []int{})
}
(*res)[currLevel] = append((*res)[currLevel], node.Val)
dfsLevel(node.Left, currLevel, res)
dfsLevel(node.Right, currLevel, res)
dfsLevel(root, 0)
return res
}

View File

@ -81,3 +81,40 @@ func search(root *TreeNode, depth int, res *[][]int) {
search(root.Left, depth+1, res)
search(root.Right, depth+1, res)
}
// 解法三 BFS
func zigzagLevelOrder1(root *TreeNode) [][]int {
res := [][]int{}
if root == nil {
return res
}
q := []*TreeNode{root}
size, i, j, lay, tmp, flag := 0, 0, 0, []int{}, []*TreeNode{}, false
for len(q) > 0 {
size = len(q)
tmp = []*TreeNode{}
lay = make([]int, size)
j = size - 1
for i = 0; i < size; i++ {
root = q[0]
q = q[1:]
if !flag {
lay[i] = root.Val
} else {
lay[j] = root.Val
j--
}
if root.Left != nil {
tmp = append(tmp, root.Left)
}
if root.Right != nil {
tmp = append(tmp, root.Right)
}
}
res = append(res, lay)
flag = !flag
q = tmp
}
return res
}

View File

@ -16,7 +16,23 @@ type TreeNode = structures.TreeNode
* }
*/
// 解法一, 直接传入需要的 slice 范围作为输入, 可以避免申请对应 inorder 索引的内存, 内存使用(leetcode test case) 4.7MB -> 4.3MB.
func buildTree(preorder []int, inorder []int) *TreeNode {
if len(preorder) == 0 {
return nil
}
root := &TreeNode{Val: preorder[0]}
for pos, node := range inorder {
if node == root.Val {
root.Left = buildTree(preorder[1:pos+1], inorder[:pos])
root.Right = buildTree(preorder[pos+1:], inorder[pos+1:])
}
}
return root
}
// 解法二
func buildTree1(preorder []int, inorder []int) *TreeNode {
inPos := make(map[int]int)
for i := 0; i < len(inorder); i++ {
inPos[inorder[i]] = i

View File

@ -16,7 +16,25 @@ type TreeNode = structures.TreeNode
* }
*/
// 解法一, 直接传入需要的 slice 范围作为输入, 可以避免申请对应 inorder 索引的内存, 内存使用(leetcode test case) 4.7MB -> 4.3MB.
func buildTree(inorder []int, postorder []int) *TreeNode {
postorderLen := len(postorder)
if len(inorder) == 0 {
return nil
}
root := &TreeNode{Val: postorder[postorderLen-1]}
postorder = postorder[:postorderLen-1]
for pos, node := range inorder {
if node == root.Val {
root.Left = buildTree(inorder[:pos], postorder[:len(inorder[:pos])])
root.Right = buildTree(inorder[pos+1:], postorder[len(inorder[:pos]):])
}
}
return root
}
// 解法二
func buildTree1(inorder []int, postorder []int) *TreeNode {
inPos := make(map[int]int)
for i := 0; i < len(inorder); i++ {
inPos[inorder[i]] = i

View File

@ -0,0 +1,45 @@
package leetcode
// 解法一 压缩版 DP
func numDistinct(s string, t string) int {
dp := make([]int, len(s)+1)
for i, curT := range t {
pre := 0
for j, curS := range s {
if i == 0 {
pre = 1
}
newDP := dp[j+1]
if curT == curS {
dp[j+1] = dp[j] + pre
} else {
dp[j+1] = dp[j]
}
pre = newDP
}
}
return dp[len(s)]
}
// 解法二 普通 DP
func numDistinct1(s, t string) int {
m, n := len(s), len(t)
if m < n {
return 0
}
dp := make([][]int, m+1)
for i := range dp {
dp[i] = make([]int, n+1)
dp[i][n] = 1
}
for i := m - 1; i >= 0; i-- {
for j := n - 1; j >= 0; j-- {
if s[i] == t[j] {
dp[i][j] = dp[i+1][j+1] + dp[i+1][j]
} else {
dp[i][j] = dp[i+1][j]
}
}
}
return dp[0][0]
}

View File

@ -0,0 +1,48 @@
package leetcode
import (
"fmt"
"testing"
)
type question115 struct {
para115
ans115
}
// para 是参数
// one 代表第一个参数
type para115 struct {
s string
t string
}
// ans 是答案
// one 代表第一个答案
type ans115 struct {
one int
}
func Test_Problem115(t *testing.T) {
qs := []question115{
{
para115{"rabbbit", "rabbit"},
ans115{3},
},
{
para115{"babgbag", "bag"},
ans115{5},
},
}
fmt.Printf("------------------------Leetcode Problem 115------------------------\n")
for _, q := range qs {
_, p := q.ans115, q.para115
fmt.Printf("【input】:%v 【output】:%v\n", p, numDistinct(p.s, p.t))
}
fmt.Printf("\n\n\n")
}

View File

@ -0,0 +1,99 @@
# [115. Distinct Subsequences](https://leetcode.com/problems/distinct-subsequences/)
## 题目
Given two strings `s` and `t`, return *the number of distinct subsequences of `s` which equals `t`*.
A string's **subsequence** is a new string formed from the original string by deleting some (can be none) of the characters without disturbing the remaining characters' relative positions. (i.e., `"ACE"` is a subsequence of `"ABCDE"` while `"AEC"` is not).
It is guaranteed the answer fits on a 32-bit signed integer.
**Example 1:**
```
Input: s = "rabbbit", t = "rabbit"
Output: 3
Explanation:
As shown below, there are 3 ways you can generate "rabbit" from S.
rabbbitrabbbitrabbbit
```
**Example 2:**
```
Input: s = "babgbag", t = "bag"
Output: 5
Explanation:
As shown below, there are 5 ways you can generate "bag" from S.
babgbagbabgbagbabgbagbabgbagbabgbag
```
**Constraints:**
- `0 <= s.length, t.length <= 1000`
- `s` and `t` consist of English letters.
## 题目大意
给定一个字符串 s 和一个字符串 t ,计算在 s 的子序列中 t 出现的个数。字符串的一个 子序列 是指,通过删除一些(也可以不删除)字符且不干扰剩余字符相对位置所组成的新字符串。(例如,"ACE" 是 "ABCDE" 的一个子序列,而 "AEC" 不是)题目数据保证答案符合 32 位带符号整数范围。
## 解题思路
- 在字符串 `s` 中最多包含多少个字符串 `t`。这里面包含很多重叠子问题,所以尝试用动态规划解决这个问题。定义 `dp[i][j]` 代表 `s[i:]` 的子序列中 `t[j:]` 出现的个数。初始化先判断边界条件。当 `i = len(s)``0≤ j < len(t)` 的时候,`s[i:]` 为空字符串,`t[j:]` 不为空,所以 `dp[len(s)][j] = 0`。当 `j = len(t)``0 ≤ i < len(s)` 的时候,`t[j:]` 不为空字符串,空字符串是任何字符串的子序列。所以 `dp[i][n] = 1`
-`i < len(s)``j < len(t)` 的时候,如果 `s[i] == t[j]`,有 2 种匹配方式,第一种将 `s[i]``t[j]` 匹配,那么 `t[j+1:]` 匹配 `s[i+1:]` 的子序列,子序列数为 `dp[i+1][j+1]`;第二种将 `s[i]` 不与 `t[j]` 匹配,`t[j:]` 作为 `s[i+1:]` 的子序列,子序列数为 `dp[i+1][j]`。综合 2 种情况,当 `s[i] == t[j]` 时,`dp[i][j] = dp[i+1][j+1] + dp[i+1][j]`
- 如果 `s[i] != t[j]`,此时 `t[j:]` 只能作为 `s[i+1:]` 的子序列,子序列数为 `dp[i+1][j]`。所以当 `s[i] != t[j]` 时,`dp[i][j] = dp[i+1][j]`。综上分析得:
$$dp[i][j] = \left\{\begin{matrix}dp[i+1][j+1]+dp[i+1][j]&,s[i]=t[j]\\ dp[i+1][j]&,s[i]!=t[j]\end{matrix}\right.$$
- 最后是优化版本。写出上述代码以后,可以发现填表的过程是从右下角一直填到左上角。填表顺序是 从下往上一行一行的填。行内从右往左填。于是可以将这个二维数据压缩到一维。因为填充当前行只需要用到它的下一行信息即可,更进一步,用到的是下一行中右边元素的信息。于是可以每次更新该行时,先将旧的值存起来,计算更新该行的时候从右往左更新。这样做即可减少一维空间,将原来的二维数组压缩到一维数组。
## 代码
```go
package leetcode
// 解法一 压缩版 DP
func numDistinct(s string, t string) int {
dp := make([]int, len(s)+1)
for i, curT := range t {
pre := 0
for j, curS := range s {
if i == 0 {
pre = 1
}
newDP := dp[j+1]
if curT == curS {
dp[j+1] = dp[j] + pre
} else {
dp[j+1] = dp[j]
}
pre = newDP
}
}
return dp[len(s)]
}
// 解法二 普通 DP
func numDistinct1(s, t string) int {
m, n := len(s), len(t)
if m < n {
return 0
}
dp := make([][]int, m+1)
for i := range dp {
dp[i] = make([]int, n+1)
dp[i][n] = 1
}
for i := m - 1; i >= 0; i-- {
for j := n - 1; j >= 0; j-- {
if s[i] == t[j] {
dp[i][j] = dp[i+1][j+1] + dp[i+1][j]
} else {
dp[i][j] = dp[i+1][j]
}
}
}
return dp[0][0]
}
```

View File

@ -0,0 +1,52 @@
package leetcode
type Node struct {
Val int
Left *Node
Right *Node
Next *Node
}
//解法一:迭代
func connect(root *Node) *Node {
if root == nil {
return root
}
q := []*Node{root}
for len(q) > 0 {
var p []*Node
// 遍历这一层的所有节点
for i, node := range q {
if i+1 < len(q) {
node.Next = q[i+1]
}
if node.Left != nil {
p = append(p, node.Left)
}
if node.Right != nil {
p = append(p, node.Right)
}
}
q = p
}
return root
}
// 解法二 递归
func connect2(root *Node) *Node {
if root == nil {
return nil
}
connectTwoNode(root.Left, root.Right)
return root
}
func connectTwoNode(node1, node2 *Node) {
if node1 == nil || node2 == nil {
return
}
node1.Next = node2
connectTwoNode(node1.Left, node1.Right)
connectTwoNode(node2.Left, node2.Right)
connectTwoNode(node1.Right, node2.Left)
}

View File

@ -0,0 +1,117 @@
package leetcode
import (
"fmt"
"testing"
)
type question116 struct {
para116
ans116
}
// para 是参数
// one 代表第一个参数
type para116 struct {
one *Node
}
// ans 是答案
// one 代表第一个答案
type ans116 struct {
one *Node
}
func newQuestionNode()*Node{
node7 := &Node{}
node7.Val = 7
node6 := &Node{}
node6.Val = 6
node5 := &Node{}
node5.Val = 5
node4 := &Node{}
node4.Val = 4
node3 := &Node{}
node3.Val = 3
node2 := &Node{}
node2.Val = 2
node1 := &Node{}
node1.Val = 1
node1.Left = node2
node1.Right = node3
node2.Left = node4
node2.Right = node5
node3.Left = node6
node3.Right = node7
return node1
}
func newResultNode()*Node{
node7 := &Node{}
node7.Val = 7
node6 := &Node{}
node6.Val = 6
node5 := &Node{}
node5.Val = 5
node4 := &Node{}
node4.Val = 4
node3 := &Node{}
node3.Val = 3
node2 := &Node{}
node2.Val = 2
node1 := &Node{}
node1.Val = 1
node1.Left = node2
node1.Right = node3
node2.Left = node4
node2.Right = node5
node3.Left = node6
node3.Right = node7
node1.Next = nil
node2.Next = node3
node3.Next = nil
node4.Next = node5
node5.Next = node6
node6.Next = node7
node7.Next = nil
return node1
}
func Test_Problem116(t *testing.T) {
qs := []question116{
{
para116{newQuestionNode()},
ans116{newResultNode()},
},
}
fmt.Printf("------------------------Leetcode Problem 116------------------------\n")
for _, q := range qs {
_, p := q.ans116, q.para116
fmt.Printf("【input】:%v ", p.one)
fmt.Printf("【output】:%v \n", connect(p.one))
}
fmt.Printf("\n\n\n")
}

View File

@ -0,0 +1,118 @@
# [116. Populating Next Right Pointers in Each Node](https://leetcode.com/problems/populating-next-right-pointers-in-each-node/)
## 题目
You are given a **perfect binary tree** where all leaves are on the same level, and every parent has two children. The binary tree has the following definition:
```
struct Node {
int val;
Node *left;
Node *right;
Node *next;
}
```
Populate each next pointer to point to its next right node. If there is no next right node, the next pointer should be set to `NULL`.
Initially, all next pointers are set to `NULL`.
**Follow up:**
- You may only use constant extra space.
- Recursive approach is fine, you may assume implicit stack space does not count as extra space for this problem.
**Example 1:**
![https://assets.leetcode.com/uploads/2019/02/14/116_sample.png](https://assets.leetcode.com/uploads/2019/02/14/116_sample.png)
```
Input: root = [1,2,3,4,5,6,7]
Output: [1,#,2,3,#,4,5,6,7,#]
Explanation:Given the above perfect binary tree (Figure A), your function should populate each next pointer to point to its next right node, just like in Figure B. The serialized output is in level order as connected by the next pointers, with '#' signifying the end of each level.
```
**Constraints:**
- The number of nodes in the given tree is less than `4096`.
- `1000 <= node.val <= 1000`
## 题目大意
给定一个 完美二叉树 ,其所有叶子节点都在同一层,每个父节点都有两个子节点。二叉树定义如下:
```jsx
struct Node {
int val;
Node *left;
Node *right;
Node *next;
}
```
填充它的每个 next 指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next 指针设置为 NULL。初始状态下所有 next 指针都被设置为 NULL。
## 解题思路
- 本质上是二叉树的层序遍历,基于广度优先搜索,将每层的节点放入队列,并遍历队列进行连接。
## 代码
```go
package leetcode
type Node struct {
Val int
Left *Node
Right *Node
Next *Node
}
//解法一:迭代
func connect(root *Node) *Node {
if root == nil {
return root
}
q := []*Node{root}
for len(q) > 0 {
var p []*Node
// 遍历这一层的所有节点
for i, node := range q {
if i+1 < len(q) {
node.Next = q[i+1]
}
if node.Left != nil {
p = append(p, node.Left)
}
if node.Right != nil {
p = append(p, node.Right)
}
}
q = p
}
return root
}
// 解法二 递归
func connect2(root *Node) *Node {
if root == nil {
return nil
}
connectTwoNode(root.Left, root.Right)
return root
}
func connectTwoNode(node1, node2 *Node) {
if node1 == nil || node2 == nil {
return
}
node1.Next = node2
connectTwoNode(node1.Left, node1.Right)
connectTwoNode(node2.Left, node2.Right)
connectTwoNode(node1.Right, node2.Left)
}
```

View File

@ -1,9 +1,5 @@
package leetcode
import (
"strconv"
)
import (
"github.com/halfrost/LeetCode-Go/structures"
)
@ -21,29 +17,20 @@ type TreeNode = structures.TreeNode
*/
func sumNumbers(root *TreeNode) int {
res, nums := 0, binaryTreeNums(root)
for _, n := range nums {
num, _ := strconv.Atoi(n)
res += num
}
res := 0
dfs(root, 0, &res)
return res
}
func binaryTreeNums(root *TreeNode) []string {
func dfs(root *TreeNode, sum int, res *int) {
if root == nil {
return []string{}
return
}
res := []string{}
sum = sum*10 + root.Val
if root.Left == nil && root.Right == nil {
return []string{strconv.Itoa(root.Val)}
*res += sum
return
}
tmpLeft := binaryTreeNums(root.Left)
for i := 0; i < len(tmpLeft); i++ {
res = append(res, strconv.Itoa(root.Val)+tmpLeft[i])
}
tmpRight := binaryTreeNums(root.Right)
for i := 0; i < len(tmpRight); i++ {
res = append(res, strconv.Itoa(root.Val)+tmpRight[i])
}
return res
dfs(root.Left, sum, res)
dfs(root.Right, sum, res)
}

View File

@ -45,4 +45,4 @@ Find the total sum of all root-to-leaf numbers.
## 解题思路
- 这一题是第 257 题的变形题,第 257 题要求输出每条从根节点到叶子节点的路径,这一题变成了把每一个从根节点到叶子节点的数字都串联起来,再累加每条路径,求出最后的总和。实际做题思路基本没变
- 运用前序遍历的思想,当从根节点出发一直加到叶子节点,每个叶子节点汇总一次。

View File

@ -0,0 +1,20 @@
package leetcode
func candy(ratings []int) int {
candies := make([]int, len(ratings))
for i := 1; i < len(ratings); i++ {
if ratings[i] > ratings[i-1] {
candies[i] += candies[i-1] + 1
}
}
for i := len(ratings) - 2; i >= 0; i-- {
if ratings[i] > ratings[i+1] && candies[i] <= candies[i+1] {
candies[i] = candies[i+1] + 1
}
}
total := 0
for _, candy := range candies {
total += candy + 1
}
return total
}

View File

@ -0,0 +1,47 @@
package leetcode
import (
"fmt"
"testing"
)
type question135 struct {
para135
ans135
}
// para 是参数
// one 代表第一个参数
type para135 struct {
ratings []int
}
// ans 是答案
// one 代表第一个答案
type ans135 struct {
one int
}
func Test_Problem135(t *testing.T) {
qs := []question135{
{
para135{[]int{1, 0, 2}},
ans135{5},
},
{
para135{[]int{1, 2, 2}},
ans135{4},
},
}
fmt.Printf("------------------------Leetcode Problem 135------------------------\n")
for _, q := range qs {
_, p := q.ans135, q.para135
fmt.Printf("【input】:%v 【output】:%v\n", p, candy(p.ratings))
}
fmt.Printf("\n\n\n")
}

View File

@ -0,0 +1,74 @@
# [135. Candy](https://leetcode.com/problems/candy/)
## 题目
There are `n` children standing in a line. Each child is assigned a rating value given in the integer array `ratings`.
You are giving candies to these children subjected to the following requirements:
- Each child must have at least one candy.
- Children with a higher rating get more candies than their neighbors.
Return *the minimum number of candies you need to have to distribute the candies to the children*.
**Example 1:**
```
Input: ratings = [1,0,2]
Output: 5
Explanation: You can allocate to the first, second and third child with 2, 1, 2 candies respectively.
```
**Example 2:**
```
Input: ratings = [1,2,2]
Output: 4
Explanation: You can allocate to the first, second and third child with 1, 2, 1 candies respectively.
The third child gets 1 candy because it satisfies the above two conditions.
```
**Constraints:**
- `n == ratings.length`
- `1 <= n <= 2 * 10^4`
- `0 <= ratings[i] <= 2 * 10^4`
## 题目大意
老师想给孩子们分发糖果,有 N 个孩子站成了一条直线老师会根据每个孩子的表现预先给他们评分。你需要按照以下要求帮助老师给这些孩子分发糖果
- 每个孩子至少分配到 1 个糖果。
- 评分更高的孩子必须比他两侧的邻位孩子获得更多的糖果。
那么这样下来,老师至少需要准备多少颗糖果呢?
## 解题思路
- 本题的突破口在于,评分更高的孩子必须比他两侧的邻位孩子获得更多的糖果,这句话。这个规则可以理解为 2 条规则,想象成按身高排队,站在下标为 0 的地方往后“看”,评分高即为个子高的,应该比前面个子矮(评分低)的分到糖果多;站在下标为 n - 1 的地方往后“看”,评分高即为个子高的,同样应该比前面个子矮(评分低)的分到糖果多。你可能会有疑问,规则都是一样的,为什么会出现至少需要多少糖果呢?因为可能出现评分一样高的同学。扫描数组两次,处理出每一个学生分别满足左规则或右规则时,最少需要被分得的糖果数量。每个人最终分得的糖果数量即为这两个数量的最大值。两次遍历结束,将所有糖果累加起来即为至少需要准备的糖果数。由于每个人至少分配到 1 个糖果,所以每个人糖果数再加一。
## 代码
```go
package leetcode
func candy(ratings []int) int {
candies := make([]int, len(ratings))
for i := 1; i < len(ratings); i++ {
if ratings[i] > ratings[i-1] {
candies[i] += candies[i-1] + 1
}
}
for i := len(ratings) - 2; i >= 0; i-- {
if ratings[i] > ratings[i+1] && candies[i] <= candies[i+1] {
candies[i] = candies[i+1] + 1
}
}
total := 0
for _, candy := range candies {
total += candy + 1
}
return total
}
```

View File

@ -26,4 +26,4 @@ Your algorithm should have a linear runtime complexity. Could you implement it w
## 解题思路
- 题目要求不能使用辅助空间,并且时间复杂度只能是线性的。
- 题目为什么要强调有一个数字出现一次其他的出现两次我们想到了异或运算的性质任何一个数字异或它自己都等于0。也就是说如果我们从头到尾依次异或数组中的每一个数字那么最终的结果刚好是那个只出现次的数字,因为那些出现两次的数字全部在异或中抵消掉了。于是最终做法是从头到尾依次异或数组中的每一个数字,那么最终得到的结果就是两个只出现一次的数字的异或结果。因为其他数字都出现了两次,在异或中全部抵消掉了。**利用的性质是 x^x = 0**。
- 题目为什么要强调有一个数字出现一次其他的出现两次我们想到了异或运算的性质任何一个数字异或它自己都等于0。也就是说如果我们从头到尾依次异或数组中的每一个数字那么最终的结果刚好是那个只出现次的数字,因为那些出现两次的数字全部在异或中抵消掉了。于是最终做法是从头到尾依次异或数组中的每一个数字,那么最终得到的结果就是两个只出现一次的数字的异或结果。因为其他数字都出现了两次,在异或中全部抵消掉了。**利用的性质是 x^x = 0**。

View File

@ -30,9 +30,9 @@ Your algorithm should have a linear runtime complexity. Could you implement it w
## 解题思路
- 这一题是第 136 题的加强版。这类题也可以扩展,在数组中每个元素都出现 5 次,找出只出现 1 次的数。
- 本题中要求找出只出现 1 次的数,出现 3 次的数都要被消除。第 136 题是消除出现 2 次的数。这一题也会相当相同的解法,出现 3 次的数也要被消除。定义状态00、10、01这 3 个状态。当一个数出现 3 次,那么它每个位置上的 1 出现的次数肯定是 3 的倍数,所以当 1 出现 3 次以后,就归零清除。如何能做到这点呢?仿造`三进制(001001)` 就可以做到。
- 本题中要求找出只出现 1 次的数,出现 3 次的数都要被消除。第 136 题是消除出现 2 次的数。这一题也会相当相同的解法,出现 3 次的数也要被消除。定义状态00、10、01这 3 个状态。当一个数出现 3 次,那么它每个位置上的 1 出现的次数肯定是 3 的倍数,所以当 1 出现 3 次以后,就归零清除。如何能做到这点呢?仿造`三进制(000110)` 就可以做到。
- 变量 ones 中记录遍历中每个位上出现 1 的个数。将它与 A[i] 进行异或,目的是:
- 每位上两者都是 1 的,表示历史统计结果 ones 出现1次、A[i]中又出现1次,则是出现 2 次,需要进位到 twos 变量中。
- 每位上两者都是 1 的,表示历史统计结果 ones 出现1次、A[i]中又出现 1 次,则是出现 2 次,需要进位到 twos 变量中。
- 每位上两者分别为 0、1 的,加入到 ones 统计结果中。
- 最后还要 & ^twos ,是为了能做到三进制,出现 3 次就清零。例如 ones = x那么 twos = 0当 twos = x那么 ones = 0
- 变量 twos 中记录遍历中每个位上出现 1 2次 的个数。与 A[i] 进行异或的目的和上述描述相同,不再赘述。
@ -41,6 +41,31 @@ Your algorithm should have a linear runtime complexity. Could you implement it w
> 在 golang 中没有 Java 中的 ~ 位操作运算符Java 中的 ~ 运算符代表按位取反。这个操作就想当于 golang 中的 ^ 运算符当做一元运算符使用的效果。
|(twos,ones)|xi|(twos'',ones')|ones'|
|:----:|:----:|:----:|:----:|
|00|0|00|0|
|00|1|01|1|
|01|0|01|1|
|01|1|10|0|
|10|0|10|0|
|10|1|00|0|
- 第一步,先将 ones -> ones'。通过观察可以看出 ones = (ones ^ nums[i]) & ^twos
|(twos,ones')|xi|twos'|
|:----:|:----:|:----:|
|00|0|0|
|01|1|0|
|01|0|0|
|00|1|1|
|10|0|1|
|10|1|0|
- 第二步,再将 twos -> twos'。这一步需要用到前一步的 ones。通过观察可以看出 twos = (twos ^ nums[i]) & ^ones。
--------------------------
这一题还可以继续扩展,在数组中每个元素都出现 5 次,找出只出现 1 次的数。那该怎么做呢思路还是一样的模拟一个五进制5 次就会消除。代码如下:
// 解法一

View File

@ -9,17 +9,16 @@ type ListNode = structures.ListNode
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
* type ListNode struct {
* Val int
* Next *ListNode
* }
*/
func hasCycle(head *ListNode) bool {
fast := head
slow := head
for slow != nil && fast != nil && fast.Next != nil {
for fast != nil && fast.Next != nil {
fast = fast.Next.Next
slow = slow.Next
if fast == slow {

View File

@ -1,6 +1,54 @@
package leetcode
import "testing"
import (
"fmt"
"testing"
"github.com/halfrost/LeetCode-Go/structures"
)
type question141 struct {
para141
ans141
}
// para 是参数
// one 代表第一个参数
type para141 struct {
one []int
}
// ans 是答案
// one 代表第一个答案
type ans141 struct {
one bool
}
func Test_Problem141(t *testing.T) {
qs := []question141{
{
para141{[]int{3, 2, 0, -4}},
ans141{false},
},
{
para141{[]int{1, 2}},
ans141{false},
},
{
para141{[]int{1}},
ans141{false},
},
}
fmt.Printf("------------------------Leetcode Problem 141------------------------\n")
for _, q := range qs {
_, p := q.ans141, q.para141
fmt.Printf("【input】:%v 【output】:%v\n", p, hasCycle(structures.Ints2List(p.one)))
}
fmt.Printf("\n\n\n")
}

View File

@ -5,46 +5,23 @@ import (
)
func evalRPN(tokens []string) int {
if len(tokens) == 1 {
i, _ := strconv.Atoi(tokens[0])
return i
}
stack, top := []int{}, 0
for _, v := range tokens {
switch v {
case "+":
{
sum := stack[top-2] + stack[top-1]
stack = stack[:top-2]
stack = append(stack, sum)
top--
}
case "-":
{
sub := stack[top-2] - stack[top-1]
stack = stack[:top-2]
stack = append(stack, sub)
top--
}
case "*":
{
mul := stack[top-2] * stack[top-1]
stack = stack[:top-2]
stack = append(stack, mul)
top--
}
case "/":
{
div := stack[top-2] / stack[top-1]
stack = stack[:top-2]
stack = append(stack, div)
top--
}
default:
{
i, _ := strconv.Atoi(v)
stack = append(stack, i)
top++
stack := make([]int, 0, len(tokens))
for _, token := range tokens {
v, err := strconv.Atoi(token)
if err == nil {
stack = append(stack, v)
} else {
num1, num2 := stack[len(stack)-2], stack[len(stack)-1]
stack = stack[:len(stack)-2]
switch token {
case "+":
stack = append(stack, num1+num2)
case "-":
stack = append(stack, num1-num2)
case "*":
stack = append(stack, num1*num2)
case "/":
stack = append(stack, num1/num2)
}
}
}

View File

@ -6,13 +6,14 @@ func twoSum167(numbers []int, target int) []int {
for i < j {
if numbers[i]+numbers[j] == target {
return []int{i + 1, j + 1}
} else if numbers[i]+numbers[j] < target {
}
if numbers[i]+numbers[j] < target {
i++
} else {
j--
}
}
return []int{-1, -1}
return nil
}
// 解法二 不管数组是否有序,空间复杂度比上一种解法要多 O(n)
@ -20,8 +21,8 @@ func twoSum167_1(numbers []int, target int) []int {
m := make(map[int]int)
for i := 0; i < len(numbers); i++ {
another := target - numbers[i]
if _, ok := m[another]; ok {
return []int{m[another] + 1, i + 1}
if idx, ok := m[another]; ok {
return []int{idx + 1, i + 1}
}
m[numbers[i]] = i
}

View File

@ -7,7 +7,7 @@ Given a positive integer, return its corresponding column title as appear in an
For example:
```
1 -> A
1 -> A
2 -> B
3 -> C
...

View File

@ -17,33 +17,23 @@ type TreeNode = structures.TreeNode
*/
func rightSideView(root *TreeNode) []int {
res := []int{}
if root == nil {
return []int{}
return res
}
queue := []*TreeNode{}
queue = append(queue, root)
curNum, nextLevelNum, res, tmp := 1, 0, []int{}, []int{}
for len(queue) != 0 {
if curNum > 0 {
node := queue[0]
if node.Left != nil {
queue = append(queue, node.Left)
nextLevelNum++
queue := []*TreeNode{root}
for len(queue) > 0 {
n := len(queue)
for i := 0; i < n; i++ {
if queue[i].Left != nil {
queue = append(queue, queue[i].Left)
}
if node.Right != nil {
queue = append(queue, node.Right)
nextLevelNum++
if queue[i].Right != nil {
queue = append(queue, queue[i].Right)
}
curNum--
tmp = append(tmp, node.Val)
queue = queue[1:]
}
if curNum == 0 {
res = append(res, tmp[len(tmp)-1])
curNum = nextLevelNum
nextLevelNum = 0
tmp = []int{}
}
res = append(res, queue[n-1].Val)
queue = queue[n:]
}
return res
}

View File

@ -1,27 +1,26 @@
package leetcode
func isHappy(n int) bool {
if n == 0 {
return false
}
res := 0
num := n
record := map[int]int{}
for {
for num != 0 {
res += (num % 10) * (num % 10)
num = num / 10
}
if _, ok := record[res]; !ok {
if res == 1 {
return true
for n != 1 {
record[n] = n
n = getSquareOfDigits(n)
for _, previous := range record {
if n == previous {
return false
}
record[res] = res
num = res
res = 0
continue
} else {
return false
}
}
return true
}
func getSquareOfDigits(n int) int {
squareOfDigits := 0
temporary := n
for temporary != 0 {
remainder := temporary % 10
squareOfDigits += remainder * remainder
temporary /= 10
}
return squareOfDigits
}

View File

@ -35,6 +35,16 @@ func Test_Problem202(t *testing.T) {
para202{19},
ans202{true},
},
{
para202{2},
ans202{false},
},
{
para202{3},
ans202{false},
},
}
fmt.Printf("------------------------Leetcode Problem 202------------------------\n")

View File

@ -1,24 +1,16 @@
package leetcode
func minSubArrayLen(s int, nums []int) int {
n := len(nums)
if n == 0 {
return 0
}
left, right, res, sum := 0, -1, n+1, 0
for left < n {
if (right+1) < n && sum < s {
right++
sum += nums[right]
} else {
func minSubArrayLen(target int, nums []int) int {
left, sum, res := 0, 0, len(nums)+1
for right, v := range nums {
sum += v
for sum >= target {
res = min(res, right-left+1)
sum -= nums[left]
left++
}
if sum >= s {
res = min(res, right-left+1)
}
}
if res == n+1 {
if res == len(nums)+1 {
return 0
}
return res

View File

@ -1,6 +1,9 @@
package leetcode
import "sort"
import (
"math/rand"
"sort"
)
// 解法一 排序,排序的方法反而速度是最快的
func findKthLargest1(nums []int, k int) int {
@ -9,36 +12,62 @@ func findKthLargest1(nums []int, k int) int {
}
// 解法二 这个方法的理论依据是 partition 得到的点的下标就是最终排序之后的下标,根据这个下标,我们可以判断第 K 大的数在哪里
// 时间复杂度 O(n),空间复杂度 O(log n),最坏时间复杂度为 O(n^2),空间复杂度 O(n)
func findKthLargest(nums []int, k int) int {
if len(nums) == 0 {
return 0
}
return selection(nums, 0, len(nums)-1, len(nums)-k)
m := len(nums) - k + 1 // mth smallest, from 1..len(nums)
return selectSmallest(nums, 0, len(nums)-1, m)
}
func selection(arr []int, l, r, k int) int {
if l == r {
return arr[l]
func selectSmallest(nums []int, l, r, i int) int {
if l >= r {
return nums[l]
}
p := partition164(arr, l, r)
if k == p {
return arr[p]
} else if k < p {
return selection(arr, l, p-1, k)
q := partition(nums, l, r)
k := q - l + 1
if k == i {
return nums[q]
}
if i < k {
return selectSmallest(nums, l, q-1, i)
} else {
return selection(arr, p+1, r, k)
return selectSmallest(nums, q+1, r, i-k)
}
}
func partition164(a []int, lo, hi int) int {
pivot := a[hi]
i := lo - 1
for j := lo; j < hi; j++ {
if a[j] < pivot {
func partition(nums []int, l, r int) int {
k := l + rand.Intn(r-l+1) // 此处为优化,使得时间复杂度期望降为 O(n),最坏时间复杂度为 O(n^2)
nums[k], nums[r] = nums[r], nums[k]
i := l - 1
// nums[l..i] <= nums[r]
// nums[i+1..j-1] > nums[r]
for j := l; j < r; j++ {
if nums[j] <= nums[r] {
i++
a[j], a[i] = a[i], a[j]
nums[i], nums[j] = nums[j], nums[i]
}
}
a[i+1], a[hi] = a[hi], a[i+1]
nums[i+1], nums[r] = nums[r], nums[i+1]
return i + 1
}
// 扩展题 剑指 Offer 40. 最小的 k 个数
func getLeastNumbers(arr []int, k int) []int {
return selectSmallest1(arr, 0, len(arr)-1, k)[:k]
}
// 和 selectSmallest 实现完全一致,只是返回值不用再截取了,直接返回 nums 即可
func selectSmallest1(nums []int, l, r, i int) []int {
if l >= r {
return nums
}
q := partition(nums, l, r)
k := q - l + 1
if k == i {
return nums
}
if i < k {
return selectSmallest1(nums, l, q-1, i)
} else {
return selectSmallest1(nums, q+1, r, i-k)
}
}

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