-
Notifications
You must be signed in to change notification settings - Fork 0
/
search.xml
1109 lines (1109 loc) · 108 KB
/
search.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<?xml version="1.0" encoding="utf-8"?>
<search>
<entry>
<title><![CDATA[从Minimum Number of Refueling Stops谈DP降维]]></title>
<url>%2F2021%2F02%2F19%2Falgorithm%2FMinimum-Number-of-Refueling-Stops%2F</url>
<content type="text"><![CDATA[DescriptionLink 给定一个target和stations,求最少加几次油可以到达目的地。 Answer这是一道DP题 dp[i][j]: 经过i个加油站加j次油最多能走多少公里。这里有个限制j <= i 当经过第i个加油站有两个选择,只有加油或者不加油两种选择。 如果不加油的话, dp[i][j] = dp[i-1][j] 如果加油的话,dp[i][j] = dp[i-1][j-1] + station[i-1][1] 最后我们遍历j, 代表经过所有车站最多加j次油可以跑多少公里。如果大于等于target那么就返回j. 如果没有结果的话就返回-1。 1234567891011121314151617181920212223242526272829303132class Solution {public: int minRefuelStops(int target, int startFuel, vector<vector<int>>& s) { int n = s.size(); // dp[i][j] 经过第i个加油站,加j次油,可以跑的最远距离 vector<vector<long>> dp(n+1, vector<long>(n+1, 0)); for(int i = 0; i <= n; ++i) { dp[i][0] = startFuel; } for(int i = 1; i <= n; ++i) { for(int j = 1; j<= i; ++j) { // 不加油 if (dp[i-1][j] >= s[i-1][0]) { dp[i][j] = dp[i-1][j]; } // 加油 if (dp[i-1][j-1] >= s[i-1][0]) { dp[i][j] = max(dp[i][j], dp[i-1][j-1] + s[i-1][1]); } } } for(int i = 0; i <= n; ++i) { if (dp[n][i] >= target) return i; } return -1; }}; Follow Up这题用了二维数组,我们观察到dp在更新的时候,只跟前有限个状态有关 dp[i][j] <=> dp[i-1][j] dp[i][j] <=> dp[i-1][j-1] 我们看到dp[i][*]总是和前一个状态dp[i-1][*]有关,因此我们可以降低一个维度,也就是把第一维也删去。变为 dp[j] <=> dp[j] dp[j] <=> dp[j-1] 但是我们要注意dp[j] = dp[j-1]. 如果按顺序更新的话dp[1] <=> dp[0]… dp[2] <=> dp[1]. 在更新dp[2]的时候使用的dp[1]是本轮更新过的,会导致答案错误,因此我们应该尝试倒序更新。dp[2] <=> dp[1]…dp[1] <=> dp[0]. 1234567891011121314151617181920212223242526272829class Solution {public: int minRefuelStops(int target, int startFuel, vector<vector<int>>& s) { int n = s.size(); // dp[i] 加i次油,可以跑的最远距离 vector<long> dp(n+1); dp[0] = startFuel; for(int i = 1; i <= n; ++i) { for(int j = i; j >= 1; --j) { // 不加油 if (dp[j] >= s[i-1][0]) { dp[j] = dp[j]; } // 加油 if (dp[j-1] >= s[i-1][0]) { dp[j] = max(dp[j], dp[j-1] + s[i-1][1]); } } } for(int i = 0; i <= n; ++i) { if (dp[i] >= target) return i; } return -1; }};]]></content>
<categories>
<category>Algorithm</category>
</categories>
<tags>
<tag>Leetcode Hard</tag>
<tag>DP</tag>
</tags>
</entry>
<entry>
<title><![CDATA[Domino and Tromino Tiling]]></title>
<url>%2F2021%2F02%2F14%2Fleetcode%2FDomino-and-Tromino-Tiling%2F</url>
<content type="text"><![CDATA[DescriptionLink 很有趣的一道题,给定一个2*N的格子,一共有2种形状,问有几种拼法。 Answer虽然只有2种形状,一种是domino, 一种是tromino, 但是由于可以旋转,所以拼的时候一共有domino2种+tromino4种=6种。最开始也是想用dp做。但是对于tromino就不适用了。论坛有个人定一个三个dp来做。https://leetcode.com/problems/domino-and-tromino-tiling/ 时间: $O(N)$空间: $O(3N)$由于只需要最多前两种的状态,所以我们也可以用常数来保存状态使得空间复杂度只有$O(1)$ 123456789101112131415161718192021222324252627class Solution {public: int numTilings(int N) { if (N == 1) return 1; int mod = 1e9+7; vector<long> dp(N+1, 0); vector<long> dpUp(N+1, 0); vector<long> dpDown(N+1, 0); dp[1] = 1; dp[2] = 2; dpUp[2] = 1; dpDown[2] = 1; for(int i = 3; i <= N; ++i) { dp[i] = (dp[i-1] + dp[i-2] + dpUp[i-1] + dpDown[i-1]) % mod; dpUp[i] = (dp[i-2] + dpDown[i-1]) % mod; dpDown[i] = (dp[i-2] + dpUp[i-1]) % mod; } return dp[N]; }};]]></content>
<categories>
<category>Leetcode</category>
</categories>
<tags>
<tag>Leetcode Medium</tag>
</tags>
</entry>
<entry>
<title><![CDATA[3Sum With Multiplicity]]></title>
<url>%2F2021%2F02%2F14%2Fleetcode%2F3Sum-With-Multiplicity%2F</url>
<content type="text"><![CDATA[DescriptionLink 3Sum的升级版,给定一个数列,然后求所有加起来和是target的子数列的个数。 Answer由于答案不是单一的,肯定根每个数字出现的次数有关,所以用一个map来储存所有数字的个数。然后我们分3种情况。假设nums[i]+nums[j]+nums[k]=target 假设三个数字都是一样的。即nums[i] == nums[j] == nums[k], 那么就是组合问题,从N个数字里面挑出3个。 假设两个数字一样。即nums[i] == nums[j] != nums[k], 也就是从N个数字里面挑出2个乘以nums[k]出现的次数。 假设三个数字都不一样。这种比较复杂。嫁入给定的数组是[1,2,3], target=6, 如果我们双循环数组,我们会得到[1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], [3,2,1]. 但是其实他们只能算一种。所以我们应该做个简单限制,当nums[i] < nums[j] < nums[k]或者nums[i] > nums[j] > nums[k]时候,我们才计算。 时间复杂度: $O(N^2)$空间复杂度: $O(N)$ 1234567891011121314151617181920212223242526class Solution {public: int threeSumMulti(vector<int>& A, int target) { unordered_map<int,long> m; for(auto c: A) { m[c]++; } long res = 0; for(auto it1: m){ for(auto it2: m) { int i = it1.first, j = it2.first, k = target - i - j; if (!m.count(k)) continue; if (i == j && j == k) { res += m[i] * (m[i]-1) * (m[i]-2) / 6; }else if (i == j && i != k) { res += m[i] * (m[i]-1) / 2 * m[k]; }else if (i < j && j < k) { res += m[i] * m[j] * m[k]; } } } return res % int(1e9+7); }};]]></content>
<categories>
<category>Leetcode</category>
</categories>
<tags>
<tag>Leetcode Medium</tag>
</tags>
</entry>
<entry>
<title><![CDATA[Minimum Limit of Balls in a Bag]]></title>
<url>%2F2021%2F02%2F14%2Fleetcode%2FMinimum-Limit-of-Balls-in-a-Bag%2F</url>
<content type="text"><![CDATA[DescriptionLink给定一个数组和一个最大操作数,每次操作都可以把其中一个数分割为任意两个正数,求最后数列里面最大的那个值的最小值。 Answer在比赛的时候,刚开始是想通过priority queue来处理最大的数,然后每次对半分,这样就可以保证最后所有数都能够相对平均。但是明显和题目实例得出来的不一样,后面又发现,其他怎么分根据maxOperation的不同也会不同,所以也没有办法用dp来做。后面看论坛的答案使用binary search来做。也就是我假设一个处理过后的最大值mid,然后遍历整个数组,看看为了变成mid得操作几次。然后全部相加看看有没有大于maxOperation. 如果大于maxOperation就表示我们取的mid值太大了,所以要取[mid+1, right] 12345678910111213141516171819202122class Solution {public: int minimumSize(vector<int> nums, int maxOperations) { int left = 1, right = 1e9; while(left < right) { int mid = left + (right-left)/2; int operations = 0; for(auto num: nums) { // 需要几步才能分成小于等于mid operations += (num-1)/mid; } if (operations > maxOperations) { left = mid+1; }else { right = mid; } } return left; }};]]></content>
<categories>
<category>Leetcode</category>
</categories>
<tags>
<tag>Leetcode Medium</tag>
</tags>
</entry>
<entry>
<title><![CDATA[Pseudo-Palindromic Paths in a Binary Tree]]></title>
<url>%2F2021%2F02%2F12%2Fleetcode%2FPseudo-Palindromic-Paths-in-a-Binary-Tree%2F</url>
<content type="text"><![CDATA[DescriptionLink给定一棵树,求可以变为Palindrom路径的数量。 Answer1可以用backtrace来做,但是效率比较差时间: O(N)空间: O(9+H) H是数的高度 12345678910111213141516171819202122232425262728293031323334class Solution {public: unordered_set<int> record; int res = 0; int pseudoPalindromicPaths (TreeNode* root) { helper(root); return res; } void helper(TreeNode* root) { if (!root) return; if (record.count(root->val)) { record.erase(root->val); }else{ record.insert(root->val); } helper(root->left); helper(root->right); if (!root->left && !root->right) { if (record.size() == 0 || record.size() == 1) { res++; } } if (record.count(root->val)) { record.erase(root->val); }else{ record.insert(root->val); } }}; Answer2还有一种方法我们不用map来保存而是用bitmask来保存每一条路径的数,用^来抵消已经出现过一次的数。最后到达根节点的时候我们只需要利用count&(count-1) == 0就可以判断count的是否只有一位为1。 123456789101112class Solution {public: int pseudoPalindromicPaths (TreeNode* root, int count = 0) { if (!root) return 0; count ^= 1 << (root->val - 1); int res = pseudoPalindromicPaths(root->left, count) + pseudoPalindromicPaths(root->right, count); if (root->left == NULL && root->right == NULL && (count & (count - 1)) == 0) { res++; } return res; }};]]></content>
<categories>
<category>Leetcode</category>
</categories>
<tags>
<tag>Leetcode Easy</tag>
</tags>
</entry>
<entry>
<title><![CDATA[Convert BST to Greater Tree]]></title>
<url>%2F2021%2F02%2F12%2Fleetcode%2FConvert-BST-to-Greater-Tree%2F</url>
<content type="text"><![CDATA[DescriptionLink给定一颗二分查找的数,对每一个数字进行更新,更新为自己的数+大于自己的节点的和。 Answer我们可以从小到大遍历整棵树,维持一个curSum, 当遍历到一个节点后,节点值加上curSum然后更新为节点值即可 1234567891011121314151617class Solution {public: int curSum = 0; TreeNode* convertBST(TreeNode* root) { if (root) { if (root->right) { convertBST(root->right); } curSum += root->val; root->val = curSum; if (root->left) { convertBST(root->left); } } return root; }};]]></content>
<categories>
<category>Leetcode</category>
</categories>
<tags>
<tag>Leetcode Easy</tag>
</tags>
</entry>
<entry>
<title><![CDATA[Maximum Swap]]></title>
<url>%2F2021%2F02%2F12%2Fleetcode%2FMaximum-Swap%2F</url>
<content type="text"><![CDATA[DescriptionLink 给定一个整数,要求对调两个字符使得这个值最大。如果不对调也是最大值的话,就返回原来的值。 Answer要使得值最大的话,我们应该使得前面的小数字与后面的大数字对调。 扫一次字符,记录每个字符最大的下标的数组bucket。 再扫一次字符,对每一个字符,我们都对第一步得到的bucket来做遍历,看看有没有下标大于目前的,切数字也大于的,有的话我们对调,并且返回就可以了。 如果遍历没能返回结果代表不存在答案,我们就返回原来的值 12345678910111213141516171819202122232425class Solution {public: int maximumSwap(int num) { string numStr = to_string(num); int n = numStr.size(); vector<int> buckets(10, -1); for(int i = 0; i < n; ++i) { buckets[numStr[i]-'0'] = i; } for(int i = 0; i < n; ++i) { for(int j = 9; j > numStr[i]-'0'; --j) { if (buckets[j] > i) { swap(numStr[buckets[j]], numStr[i]); return stoi(numStr); } } } return num; }};]]></content>
<categories>
<category>Leetcode</category>
</categories>
<tags>
<tag>Array</tag>
<tag>Leetcode Medium</tag>
<tag>Math</tag>
</tags>
</entry>
<entry>
<title><![CDATA[Closest Subsequence Sum]]></title>
<url>%2F2021%2F02%2F08%2Fleetcode%2FClosest-Subsequence-Sum%2F</url>
<content type="text"><![CDATA[DescriptionLink题目给定一个数列nums和goal. 求nums的子数列和goal的差的最小值。最直观的方法是把所有子数列的和全部求出来,然后一一和goal比较。求子数列的复杂度是$O(2^N)$。很容易就TLE。所以我们可以拆成2部当成2sum来做。 首先数列对半砍,我们求出左半边和右半边所有的子数列g1 g2 时间复杂度变成$O(2^{\frac{N}{2}})$然后我们遍历g2来找到g1中的组合使得和最接近goal. 当然我们还需要保持一个res来更新我们的最优解。如果只是双重循环g2和g1, 时间复杂度会是$O(N^2)$。因此我们选择对g1做个排序,然后通过二分查找来找。 二分查找的时候其实我们需要找到upper_bound, 也就是比和大于等于goal的第一个数。既然我们可以找到这个数,那么我们也需要找到这个数的前面那个数,来做一个比较,那个有可能是最优解并且更新我们的res Answer1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556class Solution {public: int minAbsDifference(vector<int>& nums, int goal) { int n = nums.size(); vector<int> g1; vector<int> g2; genreateSum(0, n/2, 0, nums, g1); genreateSum(n/2, n, 0, nums, g2); sort(g1.begin(), g1.end()); int res = INT_MAX; for(auto num2: g2) { int target = goal - num2; if (g1[0] > target) { res = min(res, abs(g1[0]+num2-goal)); continue; } if (g1[g1.size()-1] < target) { res = min(res, abs(g1[g1.size()-1]+num2-goal)); continue; } // 如果任何一个数都比target小,那么idx会返回g1.size(), 由于我们已经在上面一步做处理的,所以在这里不会出现 int idx = upperBound(g1, target); res = min(res, abs(g1[idx]+num2-goal)); if (idx >= 1) { res = min(res, abs(g1[idx-1]+num2-goal)); } } return res; } void genreateSum(int start, int end, int curSum, vector<int>& nums, vector<int>& list) { if (start == end) { list.push_back(curSum); return; } genreateSum(start+1, end, curSum+nums[start], nums, list); genreateSum(start+1, end, curSum, nums, list); } int upperBound(vector<int>& nums, int target) { int i = 0, j = nums.size(); while( i < j ) { int mid = i + (j-i)/2; if (nums[mid] < target) { i = mid+1; }else { j = mid; } } return i; }};]]></content>
<categories>
<category>Leetcode</category>
</categories>
<tags>
<tag>DP</tag>
<tag>Leetcode Easy</tag>
</tags>
</entry>
<entry>
<title><![CDATA[Maximum Score From Removing Stones]]></title>
<url>%2F2021%2F02%2F07%2Fleetcode%2FMaximum-Score-From-Removing-Stones%2F</url>
<content type="text"><![CDATA[DescriptionLink有三个数,每一次操作我们可以选择任意两个数减,求最多能玩几次。 Answer这道题的策略应该是优先减少最大的和第二大的。因为如果从最小的开始减,那么游戏很快就会结束,例如1, 2, 10。每一次减少后,我们都回归求新的三个数的答案+1。 followUp:由于我们本质上是扣除最大和第二大的数,然后循环再一直求下去,因此我们可以一次性剪去多个数,只要能保证最大数和第二大数在减去该数之后还能保持第一大和第二大。 12345678910111213class Solution {public: int maximumScore(int a, int b, int c) { if (a < b) return maximumScore(b, a, c); if (b < c) return maximumScore(a, c, b); if (b == 0) return 0; int cnt = max(1, b-c); return cnt + maximumScore(a - cnt, b - cnt, c); }};]]></content>
<categories>
<category>Leetcode</category>
</categories>
<tags>
<tag>Leetcode Medium</tag>
<tag>Math</tag>
<tag>Heap</tag>
</tags>
</entry>
<entry>
<title><![CDATA[Check if Array Is Sorted and Rotated]]></title>
<url>%2F2021%2F02%2F07%2Fleetcode%2FCheck-if-Array-Is-Sorted-and-Rotated%2F</url>
<content type="text"><![CDATA[DescriptionLink Answer题目要求判断一个数列是否可以向右移动几位后是否可以变为全升序的。例如有一串数列 a1 < a2 < a3 < a4 > b1 < b2 < b3 < b4,在b1的时候,是唯一一次不满足后面大于前面的。也就是说,如果该数列能移动几次就满足全升序的话,必须满足,前面比后面大出现的次数最多一次。由于最后一个数和最开始一个数是相连接的,因此我们还得判断最后一个数的第一个数的关系。 12345678910111213141516class Solution {public: bool check(vector<int>& nums) { int n = nums.size(); int found = 0; for(int i = 0; i < n; ++i) { if (nums[i] < nums[(i-1+n)%n]) { found++; } if (found > 1) { return false; } } return true; }};]]></content>
<categories>
<category>Leetcode</category>
</categories>
<tags>
<tag>Array</tag>
<tag>Leetcode Easy</tag>
</tags>
</entry>
<entry>
<title><![CDATA[Minimum Window Substring]]></title>
<url>%2F2021%2F02%2F06%2Fleetcode%2FMinimum-Window-Substring%2F</url>
<content type="text"><![CDATA[DescriptionLink Answer给定两个字符串s和t。要求返回包含t所有字符的s的最段子字符串。主要思路是用sliding window来做。思路是保持一个窗口,首先我们移动移动窗口的尾部使得能够包含t的所有字符,当我们找到之后,我们通过推进窗口的开始位置来求的最优解。 我们用一个变量reuqired来表示目前window内还需要匹配到多少字符才能符合题目要求。我们再用一个remaining数组来表示t中每个字符的个数。 我们遍历s字符串的每一个字符c 假设required不为0,我们需要延长窗口的大小,并且–remaining里的字符c,假设原来s就不包含c这个字符,那么–的结果就是负的。因此如果–之后的结果是>=0就代表我们找到了需要的字符,因此required-- 假设required为0,代表我们窗口内以及包含了所有我们需要的字符了,那我们可以尝试把窗口缩小,也就是窗口start的位置往前进,在往前进的过程中,我们需要把remaining里的相应字符给++, 如果++的结果是正数(如果t中不包含这个字符的话在上一步会是负数),代表我们需要的字符少了一个,那我们需要把required++代表下一次我们需要再重复第一个步骤来找到所需要的字符。 1234567891011121314151617181920212223242526272829class Solution {public: string minWindow(string s, string t) { vector<int> remaining(128, 0); for(auto c: t) remaining[c]++; int required = t.size(); int start = 0, i = 0, left = 0, minLen = INT_MAX; // = 是为了防止在最后一位的时候刚好找到 while(i <= s.size() && start < s.size()) { if (required) { if (i == s.size()) break; remaining[s[i]]--; if (remaining[s[i]] >= 0) required--; ++i; }else{ if ( i - start < minLen) { minLen = i-start; left = start; } remaining[s[start]]++; if (remaining[s[start]] > 0) required++; start++; } } return minLen == INT_MAX ? "" : s.substr(left, minLen); }};]]></content>
<categories>
<category>Leetcode</category>
</categories>
<tags>
<tag>Leetcode Hard</tag>
<tag>Hash Table</tag>
<tag>Two Pointers</tag>
<tag>String</tag>
<tag>Sliding Window</tag>
</tags>
</entry>
<entry>
<title><![CDATA[Path With Minimum Effort]]></title>
<url>%2F2021%2F02%2F04%2Fleetcode%2FPath-With-Minimum-Effort%2F</url>
<content type="text"><![CDATA[DescriptionLink题目要求从最左上角走到最右下角,找到一条路可以使得每一步的差的值的最大的最小值。 Answer 1没有做出来,看了答案用了dijkstra算法。设置一个 $m*n$ 的数组dist,表示每一个元素到$(0, 0)$的阶段d的最大差值。初始化都设为INT_MAX. 设置一个pq, 把最左上角的点推入,设置距离为0, 循环这个pq,我们要优先考虑d最小的元素,因为只有从最小找才有可能找到最小的最大d. 到遍历到一个点的时候,我们看它的四周的四个点,计算他们的阶段差d, 如果小于数组dist则更新目前的值,并把他们加入到pq中。 其实pq里面取出来的第一个的点是最有可能是答案要求的最优解,我们找到有可能的最优解,并且去遍历他们的身边的四个点来更新四个点的距离信息,并且加入到pq中,假设周边四个点突然出现了很大的抖动,那么pq就会把他们滞后,而开始遍历其它的点。如果把所有的点都遍历完,那么最后dist里面所储存的就是初始点到每一个点的最优解。 空间复杂度: O(MN)时间复杂度: O(MN) 12345678910111213141516171819202122232425262728293031323334353637int minimumEffortPath(vector<vector<int>>& heights) { int dirs[5] = {-1, 0, 1, 0, -1}; int n = heights.size(); int m = heights[0].size(); vector<vector<int>> dist(n, vector<int>(m, INT_MAX)); priority_queue<pair<int, int>, vector<pair<int,int>>, greater<pair<int, int>>> pq; pq.push(pair{0, 0}); while(!pq.empty()) { int d = pq.top().first, r = pq.top().second/100, c = pq.top().second%100; pq.pop(); if (d > dist[r][c]) continue; if (r == n-1 && c == m-1 ) return d; for(int i = 0; i < 4; ++i) { int nr = r+dirs[i], nc = c+dirs[i+1]; if (nr >= 0 && nc >=0 && nr < n && nc < m) { int newDist = max(d, abs(heights[r][c]-heights[nr][nc])); if (newDist < dist[nr][nc]) { dist[nr][nc] = newDist; pq.push(make_pair(newDist, nr*100+nc)); } } } } return 0;}]]></content>
<categories>
<category>Leetcode Medium</category>
</categories>
<tags>
<tag>Leetcode</tag>
<tag>Dijkstra</tag>
</tags>
</entry>
<entry>
<title><![CDATA[Find the Difference]]></title>
<url>%2F2021%2F02%2F04%2Fleetcode%2FFind-the-Difference%2F</url>
<content type="text"><![CDATA[DescriptionLink Answer这道题目给定了两个字符串,t比s多一个字符,要求找出这个字符是什么。自己做的时候用的是Map,我们可以把t的字符全部存起来,并且储存他们的数量。然后再遍历一遍s.把Map里的元素再一一删除,最后剩下的那个便是答案。 当然也可以反过来,储存s遍历t。假设找不到的话就是目前的答案。 123456789101112131415161718class Solution {public: char findTheDifference(string s, string t) { unordered_map<char, int> m; for(auto c: t) { m[c]++; } for(auto c: s) { if (!m.count(c)) return c; m[c]--; if (m[c] == 0) { m.erase(c); } } return m.begin()->first;; }}; 时间复杂度是O(N),空间复杂度也是O(N)。看了论坛里的后发现了一种空间复杂度是O(1)的方法。利用了异或的性质。 1234567891011121314151617class Solution {public: char findTheDifference(string s, string t) { char res = 0; for(auto c: t) { res ^= c; } for(auto c: s) { res ^= c; } return res; }};]]></content>
<categories>
<category>Leetcode Easy</category>
</categories>
<tags>
<tag>Leetcode</tag>
<tag>Hash Table</tag>
<tag>Bit Manipulation</tag>
</tags>
</entry>
<entry>
<title><![CDATA[House Robber II]]></title>
<url>%2F2020%2F05%2F30%2Fleetcode%2FHouse-Robber-II%2F</url>
<content type="text"><![CDATA[Explanation主要是dp的定义。因为不能同时偷取第一个和最后一个房子所以我们可以定义两个dp第一个dp是代表从第一个屋子开始偷第二个dp是代表从第二个屋子开始偷。 DP的定义为 dp[i]: 偷取前i个屋子(nums[0,i))的最大效益 dp[i] = max ( dp[i-1], dp[i-2] + nums[i-1] ) // 比较 偷取当前屋子和不偷取当前屋子的最大效益 在最近比较的时候,对于从第一个屋开始偷的,我们比较n-1的结果。和从第二个屋子开始偷的,我们计算到最后一个屋子就行。 Answer1234567891011121314151617181920212223242526272829class Solution {public: int rob(vector<int>& nums) { int n = nums.size(); if (n == 0) return 0; if ( n == 1 ) return nums[0]; vector<int> dpFirst(n+1, 0); // d[i] represents rob [0,i) houses vector<int> dpSecond(n+1, 0); dpFirst[0] = 0; dpFirst[1] = nums[0]; dpSecond[0] = 0; dpSecond[1] = 0; for(int i = 2; i <= n; ++i) { dpFirst[i] = max(dpFirst[i-1], dpFirst[i-2] + nums[i-1]); dpSecond[i] = max(dpSecond[i-1], dpSecond[i-2] + nums[i-1]); } return max(dpFirst[n-1], dpSecond[n]); }};]]></content>
<categories>
<category>Leetcode Medium</category>
<category>DP</category>
</categories>
<tags>
<tag>DP</tag>
<tag>Leetcode</tag>
</tags>
</entry>
<entry>
<title><![CDATA[Is Subsequence]]></title>
<url>%2F2020%2F02%2F16%2Fleetcode%2FIs-Subsequence%2F</url>
<content type="text"><![CDATA[Answer也不知道用DP是什么意思。 123456789101112131415class Solution {public: bool isSubsequence(string s, string t) { if (s.size() == 0 && t.size() == 0) return true; int n = s.size(); int j = 0; for(int i = 0; i < t.size(); ++i) { if (t[i] == s[j]) ++j; if (j == n) return true; } return false; }};]]></content>
<categories>
<category>Leetcode Easy</category>
<category>DP</category>
</categories>
<tags>
<tag>DP</tag>
<tag>Leetcode</tag>
</tags>
</entry>
<entry>
<title><![CDATA[Paint House]]></title>
<url>%2F2020%2F02%2F14%2Fleetcode%2FPaint-House%2F</url>
<content type="text"><![CDATA[Answer很简单的一道DP问题了,做DP应该都需要先设定DP的定义吧。这边的 dp[i][j] 的定义是如果第i个房子需要刷j类型的颜色最少是多少钱。因为数组可以用一维的所以改成一维的。 1234567891011121314151617181920class Solution {public: int minCost(vector<vector<int>>& costs) { int n = costs.size(); if (n == 0) return 0; vector<int> dp = costs[0]; for(int i = 1; i < n; ++i) { vector<int> tmp = vector<int>(3,0); tmp[0] = costs[i][0] + min(dp[1], dp[2]); tmp[1] = costs[i][1] + min(dp[0], dp[2]); tmp[2] = costs[i][2] + min(dp[0], dp[1]); dp = tmp; } return min(min(dp[0],dp[1]), dp[2]); }};]]></content>
<categories>
<category>Leetcode Easy</category>
<category>DP</category>
</categories>
<tags>
<tag>DP</tag>
<tag>Leetcode</tag>
</tags>
</entry>
<entry>
<title><![CDATA[Can Place Flowers]]></title>
<url>%2F2020%2F01%2F23%2Fleetcode%2FCan-Place-Flowers%2F</url>
<content type="text"><![CDATA[Answer12345678910111213141516171819class Solution {public: bool canPlaceFlowers(vector<int>& flowerbed, int k) { int n = flowerbed.size(); int res = 0; for(int i = 0; i < n && res < k; ++i) { int next = (i == n-1) ? 0 : flowerbed[i+1]; int before = (i == 0) ? 0 :flowerbed[i-1]; if (next == 0 && before == 0 && flowerbed[i] == 0) { res++; flowerbed[i] = 1; } } return res == k; }};]]></content>
<categories>
<category>Leetcode Easy</category>
<category>Array</category>
</categories>
<tags>
<tag>Leetcode - Array</tag>
</tags>
</entry>
<entry>
<title><![CDATA[Rotate Array]]></title>
<url>%2F2020%2F01%2F22%2Fleetcode%2FRotate-Array%2F</url>
<content type="text"><![CDATA[Answer12]]></content>
<categories>
<category>Leetcode Easy</category>
<category>Array</category>
</categories>
<tags>
<tag>Leetcode - Array</tag>
</tags>
</entry>
<entry>
<title><![CDATA[X of a Kind in a Deck of Cards]]></title>
<url>%2F2020%2F01%2F22%2Fleetcode%2FX-of-a-Kind-in-a-Deck-of-Cards%2F</url>
<content type="text"><![CDATA[Answer12345678910111213141516171819202122232425262728293031class Solution {public: bool hasGroupsSizeX(vector<int>& deck) { // number, times unordered_map<int,int> record; for(auto& num: deck) record[num]++; int minTimes = INT_MAX; for(auto& it: record) minTimes = min(minTimes, it.second); if (minTimes < 2) return false; for(int i = 2; i <= minTimes; ++i) { bool pass = true; for(auto& it: record) { if (it.second % i !=0 ) { pass = false; break; } } if (pass) return true; } return false; }}; https://www.cnblogs.com/grandyang/p/11575613.html]]></content>
<categories>
<category>Leetcode Easy</category>
<category>Array</category>
</categories>
<tags>
<tag>Leetcode - Array</tag>
</tags>
</entry>
<entry>
<title><![CDATA[Contains Duplicate II]]></title>
<url>%2F2020%2F01%2F20%2Fleetcode%2FContains-Duplicate-II%2F</url>
<content type="text"><![CDATA[Answer 1用map来做 123456789101112131415161718class Solution {public: bool containsNearbyDuplicate(vector<int>& nums, int k) { unordered_map<int,int> last; for(int i = 0; i < nums.size(); ++i) { if (last.count(nums[i])) { if ((i - last[nums[i]]) <= k) return true; } last[nums[i]] = i; } return false; }}; Answer 2第二种方法是保持一个滑动窗口,用set来做 123456789101112131415class Solution {public: bool containsNearbyDuplicate(vector<int>& nums, int k) { unordered_set<int> wd; for(int i = 0; i < nums.size(); ++i) { if (i > k) wd.erase(nums[i-k-1]); if (wd.count(nums[i])) return true; wd.insert(nums[i]); } return false; }};]]></content>
<categories>
<category>Leetcode Easy</category>
<category>Array</category>
</categories>
<tags>
<tag>Leetcode - Array</tag>
</tags>
</entry>
<entry>
<title><![CDATA[Merge Sorted Array]]></title>
<url>%2F2020%2F01%2F20%2Fleetcode%2FMerge-Sorted-Array%2F</url>
<content type="text"><![CDATA[Answer1234567891011121314151617class Solution {public: void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) { int k = m + n; while(m > 0 && n > 0) { if (nums1[m-1] > nums2[n-1]) { nums1[--k] = nums1[--m]; }else{ nums1[--k] = nums2[--n]; } } while(k > 0 && n > 0 ) nums1[--k] = nums2[--n]; }};]]></content>
<categories>
<category>Leetcode Easy</category>
<category>Array</category>
</categories>
<tags>
<tag>Leetcode - Array</tag>
</tags>
</entry>
<entry>
<title><![CDATA[Maximum Distance in Arrays]]></title>
<url>%2F2020%2F01%2F20%2Fleetcode%2FMaximum-Distance-in-Arrays%2F</url>
<content type="text"><![CDATA[Answer12]]></content>
<categories>
<category>Leetcode Easy</category>
<category>Array</category>
</categories>
<tags>
<tag>Leetcode - Array</tag>
</tags>
</entry>
<entry>
<title><![CDATA[Maximum Average Subarray I]]></title>
<url>%2F2020%2F01%2F19%2Fleetcode%2FMaximum-Average-Subarray-I%2F</url>
<content type="text"><![CDATA[Answer123456789101112131415161718class Solution {public: double findMaxAverage(vector<int>& nums, int k) { double sum = 0; for(int i = 0; i < k; ++i) sum += nums[i]; double maxSum = sum; for(int i = k; i< nums.size(); ++i) { sum += nums[i] - nums[i-k]; maxSum = max(maxSum, sum); } return maxSum / k; }};]]></content>
<categories>
<category>Leetcode Easy</category>
<category>Array</category>
</categories>
<tags>
<tag>Leetcode - Array</tag>
</tags>
</entry>
<entry>
<title><![CDATA[Largest Number At Least Twice of Others]]></title>
<url>%2F2020%2F01%2F19%2Fleetcode%2FLargest-Number-At-Least-Twice-of-Others%2F</url>
<content type="text"><![CDATA[Answer很无聊的一道题目 12345678910111213141516171819202122class Solution {public: int dominantIndex(vector<int>& nums) { int maxNum = INT_MIN; int index = -1; for(int i = 0; i < nums.size(); ++i) { if (nums[i] > maxNum) { maxNum = nums[i]; index = i; } } for(int i = 0; i < nums.size(); ++i) { if (i == index) continue; if (maxNum < nums[i]*2) return -1; } return index; }};]]></content>
<categories>
<category>Leetcode Easy</category>
<category>Array</category>
</categories>
<tags>
<tag>Leetcode - Array</tag>
</tags>
</entry>
<entry>
<title><![CDATA[Summary of Binary Search]]></title>
<url>%2F2020%2F01%2F18%2Falgorithm%2FSummary-of-Binary-Search%2F</url>
<content type="text"><![CDATA[Summary12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061/** * 左闭右开的二分查找, 在[left, right) 中间寻找 */fun commonBinarySearch(list:List<Int>, target:Int):Int { var left = 0 var right = list.size while (left < right) { val mid = left + (right-left)/2 if (list[mid] < target) left = mid+1 else right = mid } return left}/** * 寻找左边界的二分查找 */fun leftBoundBinarySearch(list:List<Int>, target:Int):Int { var left = 0 var right = list.size while (left < right) { val mid = left + (right-left)/2 if (list[mid] == target) right = mid // 收紧右边界 else if (list[mid] < target) left = mid+1 else right = mid } // target 比所有的数都大 返回-1 if (left == list.size) return -1 // 因为left有可能被遗漏 return if (list[left] == target) left else -1}/** * 寻找右边界的二分查找 */fun rightBoundBinarySearch(list:List<Int>, target:Int):Int { var left = 0 var right = list.size while (left < right) { val mid = left + (right-left)/2 if (list[mid] == target) left = mid+1 // 收紧左边界 else if (list[mid] < target) left = mid+1 else right = mid } // target 比所有的数都小 返回-1 if (left == 0) return -1 // 因为left更新的时候,需要加1,所以,最后返回下标的时候,就需要减1。 return if (list[left-1] == target) left-1 else -1} 参考 https://www.zhihu.com/question/36132386 https://blog.csdn.net/IronWring_Fly/article/details/100548061]]></content>
<categories>
<category>algorithm</category>
</categories>
<tags>
<tag>binary search</tag>
</tags>
</entry>
<entry>
<title><![CDATA[Plus One]]></title>
<url>%2F2020%2F01%2F16%2Fleetcode%2FPlus-One%2F</url>
<content type="text"><![CDATA[Answer 1这道题目跟之前两个list相加的做法很像,不过更简单。 1234567891011121314151617class Solution {public: vector<int> plusOne(vector<int>& digits) { int add = 0; int n = digits.size(); digits[n-1] += 1; // since list is not empty for(int i = digits.size()-1; i >=0; --i) { digits[i] += add; add = digits[i] / 10; digits[i] = digits[i] % 10; } if (add) digits.insert(digits.begin(), add); return digits; }}; Answer 2不过看论坛的其实更简单的做法是每一位判断是不是小于9,如果是就直接加一返回。循环外的话就在前面差一个1 1234567891011121314151617public int[] plusOne(int[] digits) { int n = digits.length; for(int i=n-1; i>=0; i--) { if(digits[i] < 9) { digits[i]++; return digits; } digits[i] = 0; } int[] newNumber = new int [n+1]; newNumber[0] = 1; return newNumber;}]]></content>
<categories>
<category>Leetcode Easy</category>
<category>Array</category>
</categories>
<tags>
<tag>Leetcode - Array</tag>
</tags>
</entry>
<entry>
<title><![CDATA[Maximize Distance to Closest Person]]></title>
<url>%2F2020%2F01%2F16%2Fleetcode%2FMaximize-Distance-to-Closest-Person%2F</url>
<content type="text"><![CDATA[Answer1234567891011121314151617class Solution {public: int maxDistToClosest(vector<int>& seats) { int n = seats.size(); int last = -1; int res = INT_MIN; for(int i = 0; i < n; ++i) { if (seats[i] == 1) { res = last < 0 ? i : max(res, (i - last)/2); last = i; } } return max(res, n - last - 1); }};]]></content>
<categories>
<category>Leetcode Easy</category>
<category>Array</category>
</categories>
<tags>
<tag>Leetcode - Array</tag>
</tags>
</entry>
<entry>
<title><![CDATA[Find Pivot Index]]></title>
<url>%2F2020%2F01%2F15%2Fleetcode%2FFind-Pivot-Index%2F</url>
<content type="text"><![CDATA[Answer 1很自然能想到的一种方法。 123456789101112131415161718class Solution {public: int pivotIndex(vector<int>& nums) { int left = 0, right = 0; for(int num: nums) right += num; for(int i = 0; i < nums.size(); ++i) { if (i > 0) left += nums[i-1]; right -= nums[i]; if (left == right) return i; } return -1; }}; Answer 2参考discuss的答案。感觉用while比for更好 12345678910111213141516class Solution {public: int pivotIndex(vector<int>& nums) { int total = 0; for(int num: nums) total += num; int i = 0, currSum = 0; while( i < nums.size()) { if (currSum * 2 == total - nums[i]) return i; currSum += nums[i++]; } return -1; }};]]></content>
<categories>
<category>Leetcode Easy</category>
<category>Array</category>
</categories>
<tags>
<tag>Leetcode - Array</tag>
</tags>
</entry>
<entry>
<title><![CDATA[Remove Duplicates from Sorted Array]]></title>
<url>%2F2020%2F01%2F15%2Fleetcode%2FRemove-Duplicates-from-Sorted-Array%2F</url>
<content type="text"><![CDATA[Answer123456789101112131415class Solution {public: int removeDuplicates(vector<int>& nums) { int n = nums.size(); int cnt = 0; for(int i = 1; i< n; ++i) { if (nums[i] == nums[i-1]) ++cnt; else nums[i-cnt] = nums[i]; // 相当于offset,往前推几位 } return n - cnt; }};]]></content>
<categories>
<category>Leetcode Easy</category>
<category>Array</category>
</categories>
<tags>
<tag>Leetcode - Array</tag>
</tags>
</entry>
<entry>
<title><![CDATA[Add to Array-Form of Integer]]></title>
<url>%2F2020%2F01%2F14%2Fleetcode%2FAdd-to-Array-Form-of-Integer%2F</url>
<content type="text"><![CDATA[Answer123456789101112131415161718class Solution {public: vector<int> addToArrayForm(vector<int>& A, int K) { for(int i = A.size()-1; i >= 0 && K > 0; --i) { A[i] += K; K = A[i] / 10; A[i] = A[i] % 10; } while ( K != 0) { A.insert(A.begin(), K % 10); K = K / 10; } return A; }};]]></content>
<categories>
<category>Leetcode Easy</category>
<category>Array</category>
</categories>
<tags>
<tag>Leetcode - Array</tag>
</tags>
</entry>
<entry>
<title><![CDATA[Two Sum]]></title>
<url>%2F2020%2F01%2F14%2Fleetcode%2FTwo-Sum%2F</url>
<content type="text"><![CDATA[Answer很经典的一道题目了,这边用hashmap做。也可以用双指针来做。这样不用耗费额外的空间复杂度且时间复杂度也是O(n) 123456789101112131415161718class Solution {public: vector<int> twoSum(vector<int>& nums, int target) { unordered_map<int,int> map; for(int i = 0; i < nums.size(); ++i) { map[nums[i]] = i; } for(int i = 0; i < nums.size(); ++i) { int found = target - nums[i]; if (map.count(found) != 0 && map[found] != i) return vector<int>{i, map[found]}; } return vector<int>{-1,-1}; }};]]></content>
<categories>
<category>Leetcode Easy</category>
<category>Array</category>
</categories>
<tags>
<tag>Leetcode - Array</tag>
</tags>
</entry>
<entry>
<title><![CDATA[Longest Continuous Increasing Subsequence]]></title>
<url>%2F2020%2F01%2F14%2Fleetcode%2FLongest-Continuous-Increasing-Subsequence%2F</url>
<content type="text"><![CDATA[Answer 11234567891011121314151617181920212223class Solution {public: int findLengthOfLCIS(vector<int>& nums) { if (nums.size() == 0) return 0; // dp[i] -> [0,i] subarray endwith nums[i] vector<int> dp(nums.size(), 1); int res = 1; for(int i = 1; i< nums.size(); ++i) { if (nums[i] > nums[i-1]) dp[i] = dp[i-1] + 1; else dp[i] = 1; // cout << dp[i] << endl; res = max(res, dp[i]); } return res; }}; Answer 21234567891011121314class Solution {public: int findLengthOfLCIS(vector<int>& nums) { int n = nums.size(); int cnt = 0; int res = 0; for (int i = 0; i < n; ++i) { if (i == 0 || nums[i] > nums[i-1]) res = max(res, ++cnt); else cnt = 1; } return res; }};]]></content>
<categories>
<category>Leetcode Easy</category>
<category>Array</category>
</categories>
<tags>
<tag>Leetcode</tag>
<tag>Array</tag>
</tags>
</entry>
<entry>
<title><![CDATA[Maximum Subarray]]></title>
<url>%2F2020%2F01%2F13%2Fleetcode%2FMaximum-Subarray%2F</url>
<content type="text"><![CDATA[Answerdp[i]的定义是 nums[0,i]的最大子数列。那么dp[i+1] = (dp[0,i] > 0 ? dp[i] : 0) + nums[i+1]因为如果前面的子数列为负数的话,一定无法是答案,因为负数加上任何数一定是小于本身的。 12345678910111213141516class Solution {public: int maxSubArray(vector<int>& nums) { int res = INT_MIN; vector<int> dp(nums.size(),0); dp[0] = nums[0]; for(int i = 1; i < nums.size(); ++i) { dp[i] = nums[i] + (dp[i-1] > 0 ? dp[i-1] : 0) ; res = max(res, dp[i]); } return res; }};]]></content>
<categories>
<category>Leetcode Easy</category>
<category>Array</category>
</categories>
<tags>
<tag>Leetcode</tag>
<tag>Array</tag>
</tags>
</entry>
<entry>
<title><![CDATA[Pascal's Triangle II]]></title>
<url>%2F2020%2F01%2F11%2Fleetcode%2FPascal-s-Triangle-II%2F</url>
<content type="text"><![CDATA[Answer1234567891011121314151617class Solution {public: vector<int> getRow(int rowIndex) { vector<int> res(rowIndex+1,0); res[0] = 1; for(int i = 1; i < rowIndex + 1; ++i) { for(int j = i; j >= 1; --j) { res[j] += res[j-1]; } } return res; }};]]></content>
<categories>
<category>Leetcode Easy</category>
<category>Array</category>
</categories>
<tags>
<tag>Leetcode</tag>
<tag>Array</tag>
</tags>
</entry>
<entry>
<title><![CDATA[Remove Element]]></title>
<url>%2F2020%2F01%2F09%2Fleetcode%2FRemove-Element%2F</url>
<content type="text"><![CDATA[Answer12345678910111213class Solution {public: int removeElement(vector<int>& nums, int val) { int j = 0; for(int i = 0; i < nums.size(); ++i) { if(nums[i] != val) nums[j++] = nums[i]; } return j; }};]]></content>
<categories>
<category>Leetcode Easy</category>
<category>Array</category>
</categories>
<tags>
<tag>Leetcode</tag>
<tag>Array</tag>
</tags>
</entry>
<entry>
<title><![CDATA[Number of Equivalent Domino Pairs]]></title>
<url>%2F2020%2F01%2F09%2Fleetcode%2FNumber-of-Equivalent-Domino-Pairs%2F</url>
<content type="text"><![CDATA[Answer用了一个index来识别是否是相同的domino 123456789101112131415161718class Solution {public: int numEquivDominoPairs(vector<vector<int>>& dominoes) { int res = 0; unordered_map<int, int> count; for(auto& domino: dominoes) { int index = max(domino[0], domino[1]) * 10 + min(domino[0], domino[1]); count[index]++; } for(auto& it: count) { res += it.second * (it.second - 1) / 2; } return res; }};]]></content>
<categories>
<category>Leetcode Easy</category>
<category>Array</category>
</categories>
<tags>
<tag>Leetcode</tag>
<tag>Array</tag>
</tags>
</entry>
<entry>
<title><![CDATA[Pairs of Songs With Total Durations Divisible by 60]]></title>
<url>%2F2020%2F01%2F09%2Fleetcode%2FPairs-of-Songs-With-Total-Durations-Divisible-by-60%2F</url>
<content type="text"><![CDATA[Answer这道题可以想象成是2sum,但是两个相加的数其实不是数字本身,需要做一定的处理首先是要满足能被60整除,需要找到两个数满足(x+t) % 60等价于x%60 = 60 - t%60x%60的范围是 [0,59]60 - t%60的范围是 [1,60] 所以等式应该变换成x%60 = (60 - t%60)%60 之后遍历储存x%60然后计算 (60 - t%60)%60是否存在,如果存在就代表找到了相应的可以和x相加被60整除的数字 12345678910111213141516171819class Solution {public: int numPairsDivisibleBy60(vector<int>& time) { unordered_map<int,int> count; int res = 0; for(auto& t : time) { int target = (60 - t % 60)%60; res += count[target]; count[t%60]++; } return res; }};]]></content>
<categories>
<category>Leetcode Easy</category>
<category>Array</category>
</categories>
<tags>
<tag>Leetcode</tag>
<tag>Array</tag>
</tags>
</entry>
<entry>
<title><![CDATA[[Array][Easy] Check If It Is a Straight Line]]></title>
<url>%2F2020%2F01%2F01%2Fleetcode%2FArray-Easy-Check-If-It-Is-a-Straight-Line%2F</url>
<content type="text"><![CDATA[Answer为了避免除以0,所以用乘法 12345678910111213141516class Solution {public: bool checkStraightLine(vector<vector<int>>& cord) { for(int i = 0; i < cord.size()-2; ++i) { int k1 = (cord[i+1][0] - cord[i][0]) * (cord[i+2][1] - cord[i+1][1]); int k2 = (cord[i+1][1] - cord[i][1]) * (cord[i+2][0] - cord[i+1][0]); if (k1 != k2) return false; } return true; }};]]></content>
<categories>
<category>Leetcode Easy</category>
<category>Array</category>
</categories>
<tags>
<tag>Leetcode</tag>
<tag>Array</tag>
</tags>
</entry>
<entry>
<title><![CDATA[830. Positions of Large Groups]]></title>
<url>%2F2019%2F12%2F27%2Fleetcode%2F830-Positions-of-Large-Groups%2F</url>
<content type="text"><![CDATA[Answer12345678910111213141516class Solution {public: vector<vector<int>> largeGroupPositions(string S) { vector<vector<int>> res; for(int i = 0, j = 0; i < S.size(); i = j) { while(S[i] == S[j]) j++; if (j - i >= 3) res.push_back(vector<int>{i, j-1}); } return res; }};]]></content>
<categories>
<category>Leetcode Easy</category>
<category>Array</category>
</categories>
<tags>
<tag>Leetcode</tag>
<tag>Array</tag>
</tags>
</entry>
<entry>
<title><![CDATA[746. Min Cost Climbing Stairs]]></title>
<url>%2F2019%2F12%2F26%2Fleetcode%2F746-Min-Cost-Climbing-Stairs%2F</url>
<content type="text"><![CDATA[Answer 1DP 1234567891011class Solution {public: int minCostClimbingStairs(vector<int>& cost) { int n = cost.size(); for(int i = 2; i < n; ++i) { cost[i] += min(cost[i-2], cost[i-1]); } return min(cost[n-1], cost[n-2]); }}; Answer 2慢很多 1234567891011121314class Solution {public: unordered_map<int,int> memo; int minCostClimbingStairs(vector<int>& cost) { return min(helper(cost, 0), helper(cost,1)); } int helper(vector<int>&cost, int i) { if(i == cost.size() - 1 || i == cost.size() - 2) return cost[i]; if (memo.count(i+1) == 0) memo[i+1] = helper(cost, i+1); if (memo.count(i+2) == 0) memo[i+2] = helper(cost, i+2); return cost[i] + min(memo[i+1], memo[i+2]); }};]]></content>
<categories>
<category>Leetcode Easy</category>
<category>Array</category>
</categories>
<tags>
<tag>Leetcode</tag>
<tag>Array</tag>
</tags>
</entry>
<entry>
<title><![CDATA[121. Best Time to Buy and Sell Stock]]></title>
<url>%2F2019%2F12%2F26%2Fleetcode%2F121-Best-Time-to-Buy-and-Sell-Stock%2F</url>
<content type="text"><![CDATA[Answer因为只能交易一次,所以肯定是一个最大值减去最小值就是答案。但是有个条件是最小值必须在最大的左边。所以遍历这个数列,然后更新最小值。同时计算最大利益 1234567891011121314class Solution {public: int maxProfit(vector<int>& prices) { int res = 0; int minPrice = INT_MAX; for(int i = 0; i < prices.size(); ++i) { res = max(prices[i] - minPrice, res); minPrice = min(prices[i], minPrice); } return res; }};]]></content>
<categories>
<category>Leetcode Easy</category>
<category>Array</category>
</categories>
<tags>
<tag>Leetcode</tag>
<tag>Array</tag>
</tags>
</entry>
<entry>
<title><![CDATA[717. 1-bit and 2-bit Characters]]></title>
<url>%2F2019%2F12%2F26%2Fleetcode%2F717-1-bit-and-2-bit-Characters%2F</url>
<content type="text"><![CDATA[Answer12345678910111213class Solution {public: bool isOneBitCharacter(vector<int>& bits) { int cnt = 0; for(int i = bits.size()-2; i >= 0; --i) { if (bits[i] == 1) ++cnt; else break; } return cnt % 2 == 0; }};]]></content>
<categories>
<category>Leetcode Easy</category>
<category>Array</category>
</categories>
<tags>
<tag>Leetcode</tag>
<tag>Array</tag>
</tags>
</entry>
<entry>
<title><![CDATA[118. Pascal's Triangle]]></title>
<url>%2F2019%2F12%2F25%2Fleetcode%2F118-Pascal-s-Triangle%2F</url>
<content type="text"><![CDATA[Answer12345678910111213141516171819class Solution {public: vector<vector<int>> generate(int numRows) { vector<vector<int>> res(numRows); for (int i = 0; i < numRows; ++i) { res[i].resize(i+1); res[i][0] = 1, res[i][i] = 1; for (int j = 1; j < i; ++j) { res[i][j] = res[i-1][j-1] + res[i-1][j]; } } return res; }};]]></content>
<categories>
<category>Leetcode Easy</category>
<category>Array</category>
</categories>
<tags>
<tag>Leetcode</tag>
<tag>Array</tag>
</tags>
</entry>
<entry>
<title><![CDATA[268. Missing Number]]></title>
<url>%2F2019%2F12%2F24%2Fleetcode%2F268-Missing-Number%2F</url>
<content type="text"><![CDATA[Answer 112345678910111213class Solution {public: int missingNumber(vector<int>& nums) { int tmp = 0; for(int i = 0; i < nums.size(); ++i) { tmp += nums[i] - i; } return nums.size() - tmp; }}; Answer 212345678910111213class Solution {public: int missingNumber(vector<int>& nums) { int res = nums.size(); for(int i = 0; i < nums.size(); ++i) { res = res ^ i; res = res ^ nums[i]; } return res; }};]]></content>
<categories>
<category>Leetcode Easy</category>
<category>Array</category>
</categories>
<tags>
<tag>Leetcode</tag>
<tag>Array</tag>
</tags>
</entry>
<entry>
<title><![CDATA[661. Image Smoother]]></title>
<url>%2F2019%2F12%2F24%2Fleetcode%2F661-Image-Smoother%2F</url>
<content type="text"><![CDATA[Answer 1时间复杂度O(N^2), 空间复杂度也是O(N^2)没有智慧的一种解法 123456789101112131415161718192021222324252627class Solution {public: vector<vector<int>> imageSmoother(vector<vector<int>>& M) { vector<vector<int>> res = M; for(int i = 0; i < M.size(); ++i) { for(int j = 0; j < M[0].size(); ++j) { res[i][j] = sumOfNine(M, i, j); } } return res; } int sumOfNine(vector<vector<int>>& M, int a, int b) { int cul = 0; int cnt = 0; for(int i = a-1; i <= a + 1; ++i) { for(int j = b-1; j <= b+1; ++j) { if (i < 0 || i >= M.size() || j < 0 || j >= M[0].size()) continue; cul += M[i][j]; cnt ++; } } return cul / cnt; }}; Answer 2另外一种方法可以做到O(1)空间复杂度,因为题目给了数值是[0-255],所以我们可以用8bits来储存原来的数字。剩余9-16bit来储存新的数字。 123456789101112131415161718192021222324252627282930313233class Solution {public: vector<vector<int>> imageSmoother(vector<vector<int>>& M) { vector<vector<int>> dirs = {{0,1},{0,-1},{1,0},{-1,0},{-1,-1},{1,1},{-1,1},{1,-1}}; for (int i = 0; i < M.size(); ++i) { for(int j = 0; j < M[0].size(); ++j) { int cnt = 1, tmp = M[i][j]; for(auto dir: dirs) { int a = i + dir[0], b = j + dir[1]; if (a < 0 || a >= M.size() || b < 0 || b >= M[0].size()) continue; cnt++; tmp += M[a][b] & 0xFF; } M[i][j] |= (tmp/cnt) << 8; } } for (int i = 0; i < M.size(); ++i) { for(int j = 0; j < M[0].size(); ++j) { M[i][j] >>= 8; } } return M; } };]]></content>
<categories>
<category>Leetcode Easy</category>
<category>Array</category>
</categories>
<tags>
<tag>Leetcode</tag>
<tag>Array</tag>
</tags>
</entry>
<entry>
<title><![CDATA[167. Two Sum II - Input array is sorted]]></title>
<url>%2F2019%2F12%2F23%2Fleetcode%2F167-Two-Sum-II-Input-array-is-sorted%2F</url>
<content type="text"><![CDATA[Answer 12sum是很经典的题目了,最简单的形式应该是用map最初。现在由于题目给了是排序过的,我们可以使用二分查找复杂度是O(N) 12345678910111213141516171819202122232425262728class Solution {public: vector<int> twoSum(vector<int>& numbers, int target) { for(int i = 0; i < numbers.size(); ++i) { int tar = target - numbers[i]; int found = binarySearch(numbers, tar, i+1, numbers.size()-1); if (found != -1) return vector<int>{i+1, found+1}; } return vector<int>{-1,-1}; } int binarySearch(vector<int>& nums, int target, int i, int j) { while( i <= j) { int mid = i + (j-i)/2; if (nums[mid] == target) return mid; if (nums[mid] < target) i = mid+1; else j = mid-1; } return -1; }}; Answer 2另外一种方法的复杂度也是O(N),但是不需要二分查找 123456789101112131415161718class Solution {public: vector<int> twoSum(vector<int>& numbers, int target) { int i = 0, j = numbers.size()-1; while( i < j ) { int currSum = numbers[i] + numbers[j]; if ( currSum == target) return vector<int>{i+1,j+1}; if (currSum > target) j--; else i++; } return vector<int>{-1,-1}; }};]]></content>
<categories>
<category>Leetcode Easy</category>
<category>Array</category>
</categories>
<tags>
<tag>Leetcode</tag>
<tag>Array</tag>
</tags>
</entry>
<entry>
<title><![CDATA[122. Best Time to Buy and Sell Stock II]]></title>
<url>%2F2019%2F12%2F20%2Fleetcode%2F122-Best-Time-to-Buy-and-Sell-Stock-II%2F</url>
<content type="text"><![CDATA[AnswerPeak Valley Approach 123456789101112class Solution {public: int maxProfit(vector<int>& prices) { int res = 0; for(int i = 1; i < prices.size(); ++i) { if (prices[i] > prices[i-1]) res += prices[i] - prices[i-1]; } return res; }};]]></content>
<categories>
<category>Leetcode Easy</category>
<category>Array</category>
</categories>
<tags>
<tag>Leetcode</tag>
<tag>Array</tag>
</tags>
</entry>
<entry>
<title><![CDATA[217. Contains Duplicate]]></title>
<url>%2F2019%2F12%2F20%2Fleetcode%2F217-Contains-Duplicate%2F</url>
<content type="text"><![CDATA[Answer时间复杂度O(N),但是空间复杂度也是O(N)似乎没有空间复杂度O(1)的方法 123456789class Solution {public: bool containsDuplicate(vector<int>& nums) { unordered_set<int> set(nums.begin(), nums.end()); return set.size() != nums.size(); }};]]></content>
<categories>
<category>Leetcode Easy</category>
<category>Array</category>
</categories>
<tags>
<tag>Leetcode</tag>
<tag>Array</tag>
</tags>
</entry>
<entry>
<title><![CDATA[448. Find All Numbers Disappeared in an Array]]></title>
<url>%2F2019%2F12%2F19%2Fleetcode%2F448-Find-All-Numbers-Disappeared-in-an-Array%2F</url>
<content type="text"><![CDATA[思路因为题目说只会出现一次或者两次,所以思路就是遍历一遍每个数字,对每个数字作为index-1(因为从1开始),然后翻转那个nums[index]于是没有出现的index是不会被翻转的,所以之后便利一遍找到大于0的也就是没有被翻转的, 那个i+1,就是答案之一 Answer123456789101112131415161718class Solution {public: vector<int> findDisappearedNumbers(vector<int>& nums) { for(int i = 0; i < nums.size(); ++i) { int index = abs(nums[i]) - 1; // 因为nums[i] 有可能是被翻转成负数的了 if (nums[index] > 0) nums[index] = -nums[index]; } vector<int> res; for(int i = 0; i < nums.size(); ++i) { if (nums[i] > 0) res.push_back(i + 1); } return res; }};]]></content>
<categories>
<category>Leetcode Easy</category>
<category>Array</category>
</categories>
<tags>
<tag>Leetcode</tag>
<tag>Array</tag>
</tags>
</entry>
<entry>
<title><![CDATA[169. Majority Element]]></title>
<url>%2F2019%2F12%2F18%2Fleetcode%2F169-Majority-Element%2F</url>
<content type="text"><![CDATA[Answer 1第一种方法很简单,很容易想到。时间复杂度是O(N),但是空间复杂度也是O(N) 12345678910111213141516class Solution {public: int majorityElement(vector<int>& nums) { int n = nums.size(); unordered_map<int,int> map; for(auto& n: nums) map[n]++; for(auto& it: map) { if (it.second > n/2) return it.first; } return 0; }}; Answer 2在论坛还有一种很聪明的方法.空间复杂度是O(N),当前遍历的值等于目前的major的话就加1,否则就减1,对于数列在[0…i] 里面寻找major,那么在什么情况下就知道目前的major不是真的major了呢,就是count减到0的时候。因为题目是major是> n/2的 123456789101112131415161718class Solution {public: int majorityElement(vector<int>& nums) { int major = nums[0], count = 1; for(int i = 1; i < nums.size(); ++i) { if (count == 0) { count++; major = nums[i]; }else if (nums[i] == major) count++; else count--; } return major; }};]]></content>
<categories>
<category>Leetcode Easy</category>
<category>Array</category>
</categories>
<tags>
<tag>Leetcode</tag>
<tag>Array</tag>
</tags>
</entry>
<entry>
<title><![CDATA[1184. Distance Between Bus Stops]]></title>
<url>%2F2019%2F12%2F17%2Fleetcode%2F1184-Distance-Between-Bus-Stops%2F</url>
<content type="text"><![CDATA[Answer很普通的一道题目,画个图就知道了 123456789101112131415161718class Solution {public: int distanceBetweenBusStops(vector<int>& distance, int start, int destination) { int small = min(start, destination); int large = max(start, destination); int case1 = 0; for (int i = 0; i < distance.size(); ++i) { if (i >= small && i < large) continue; case1 += distance[i]; } int case2 = 0; for(int i = small; i < large; ++i) case1 += distance[i]; return min(case1, case2); }};]]></content>
<categories>
<category>Leetcode Easy</category>
<category>Array</category>
</categories>
<tags>
<tag>Leetcode</tag>
<tag>Array</tag>
</tags>
</entry>
<entry>
<title><![CDATA[283. Move Zeroes]]></title>
<url>%2F2019%2F12%2F15%2Fleetcode%2F283-Move-Zeroes%2F</url>
<content type="text"><![CDATA[Answer复杂度O(n) 1234567891011121314151617class Solution {public: void moveZeroes(vector<int>& nums) { int i = 0, j = 0; for(int i = 0; i < nums.size(); ++i) { // 有多少个非0 这个就会被执行多少次 if (nums[i] != 0) nums[j++] = nums[i]; } // 最后再补齐0 for(; j < nums.size(); ++j) nums[j] = 0; return nums }};]]></content>
<categories>
<category>Leetcode Easy</category>
<category>Array</category>
</categories>
<tags>
<tag>Leetcode</tag>
<tag>Array</tag>
</tags>
</entry>
<entry>
<title><![CDATA[485. Max Consecutive Ones]]></title>
<url>%2F2019%2F12%2F13%2Fleetcode%2F485-Max-Consecutive-Ones%2F</url>
<content type="text"><![CDATA[Description485. Max Consecutive Ones Answer很简单的一道题目了 1234567891011121314class Solution {public: int findMaxConsecutiveOnes(vector<int>& nums) { int curr = 0; int res = 0; for(auto& n: nums) { curr = ( curr + n ) * n; res = max(curr, res); } return res; }};]]></content>
<categories>
<category>Leetcode Easy</category>
<category>Array</category>
</categories>
<tags>
<tag>Leetcode</tag>
<tag>Array</tag>
</tags>
</entry>
<entry>
<title><![CDATA[896. Monotonic Array]]></title>
<url>%2F2019%2F12%2F13%2Fleetcode%2F896-Monotonic-Array%2F</url>
<content type="text"><![CDATA[Answer 1最简单的方法就是两种各判断一遍,复杂度O(N) 1234567891011121314151617181920class Solution {public: bool isMonotonic(vector<int>& A) { return increasing(A) || decreasing(A); } bool increasing(vector<int>& A) { for(int i = 1; i < A.size(); ++i) { if (A[i] < A[i-1]) return false; } return true; } bool decreasing(vector<int>& A) { for(int i = 1; i < A.size(); ++i) { if (A[i] > A[i-1]) return false; } return true; }}; Answer 2更简洁的方法 1234567891011class Solution {public: bool isMonotonic(vector<int>& A) { int incFlag = true, decFlag = true; for(int i = 1; i < A.size(); ++i) { incFlag &= A[i] >= A[i-1]; decFlag &= A[i] <= A[i-1]; } return incFlag || decFlag; }};]]></content>
<categories>
<category>Leetcode Easy</category>
<category>Array</category>
</categories>
<tags>
<tag>Leetcode</tag>
<tag>Array</tag>
</tags>
</entry>
<entry>
<title><![CDATA[1013. Partition Array Into Three Parts With Equal Sum]]></title>
<url>%2F2019%2F12%2F12%2Fleetcode%2F1013-Partition-Array-Into-Three-Parts-With-Equal-Sum%2F</url>
<content type="text"><![CDATA[Answer1234567891011121314151617181920212223// O(n)class Solution {public: bool canThreePartsEqualSum(vector<int>& A) { int average = 0; for(auto& n : A) average += n; average /= 3; int cnt = 0; int curr = 0; for (int i = 0; i < A.size(); ++i) { curr += A[i]; if(curr != average) continue; else if(++cnt == 3) return true; curr = 0; } return false; }};]]></content>
<categories>
<category>Leetcode Easy</category>
<category>Array</category>
</categories>
<tags>
<tag>Leetcode</tag>
<tag>Array</tag>
</tags>
</entry>
<entry>
<title><![CDATA[888. Fair Candy Swap]]></title>
<url>%2F2019%2F12%2F10%2Fleetcode%2F888-Fair-Candy-Swap%2F</url>
<content type="text"><![CDATA[Answer123456789101112131415161718192021222324252627// sumA - cA[i] + cB[j] = sumB - cB[j] + cA[i]// => cA[i] - cB[j] = (sumA - sumB)/2 class Solution {public: vector<int> fairCandySwap(vector<int>& A, vector<int>& B) { unordered_set<int> setA; unordered_set<int> setB; int sumA = 0, sumB; for(auto& n : A) { setA.insert(n); sumA += n; } for(auto& n : B) { setB.insert(n); sumB += n; } for(int value : setA) { int target = 2*value + sumB - sumA; if (setB.count(target) != 0) return vector<int>{value, target}; } return vector<int>{0, 0}; }};]]></content>
<categories>
<category>Leetcode Easy</category>
<category>Array</category>
</categories>
<tags>
<tag>Leetcode</tag>
<tag>Array</tag>
</tags>
</entry>
<entry>
<title><![CDATA[1170. Compare Strings by Frequency of the Smallest Character]]></title>
<url>%2F2019%2F12%2F09%2Fleetcode%2F1170-Compare-Strings-by-Frequency-of-the-Smallest-Character%2F</url>
<content type="text"><![CDATA[Answer 1思想是计算words每个词的频率然后累加,最后计算queries里的每个query频率然后根据累加的累加的结果就可以知道比自己频率大的数量有多少复杂度是O(N) 12345678910111213141516171819202122232425262728293031323334class Solution {public: vector<int> numSmallerByFrequency(vector<string>& queries, vector<string>& words) { int n = queries.size(); int m = words.size(); vector<int> accumFreq(2000,0); for(auto word: words) { accumFreq[getF(word)]++; } for (int i = 1; i < 2000; ++i) accumFreq[i] += accumFreq[i-1]; vector<int> res(n,0); for(int i = 0; i < n; ++i) { int f = getF(queries[i]); res[i] = m-accumFreq[f]; } return res; } int getF(string query) { vector<int> freqs(26,0); for(auto& c : query) freqs[c - 'a']++; for(int freq: freqs) { if (freq!=0) return freq; } return 0; }}; Answer 1思想是计算words每个词的频率然后累加,最后计算queries里的每个query频率然后根据累加的累加的结果就可以知道比自己频率大的数量有多少复杂度是O(N) 12345678910111213141516171819202122232425262728293031323334class Solution {public: vector<int> numSmallerByFrequency(vector<string>& queries, vector<string>& words) { int n = queries.size(); int m = words.size(); vector<int> accumFreq(2000,0); for(auto word: words) { accumFreq[getF(word)]++; } for (int i = 1; i < 2000; ++i) accumFreq[i] += accumFreq[i-1]; vector<int> res(n,0); for(int i = 0; i < n; ++i) { int f = getF(queries[i]); res[i] = m-accumFreq[f]; } return res; } int getF(string query) { vector<int> freqs(26,0); for(auto& c : query) freqs[c - 'a']++; for(int freq: freqs) { if (freq!=0) return freq; } return 0; }};]]></content>
<categories>
<category>Leetcode Easy</category>
<category>Array</category>
</categories>
<tags>
<tag>Leetcode</tag>
<tag>Array</tag>
</tags>
</entry>
<entry>
<title><![CDATA[1089. Duplicate Zeros]]></title>
<url>%2F2019%2F12%2F07%2Fleetcode%2F1089-Duplicate-Zeros%2F</url>
<content type="text"><![CDATA[Answer这道题其实不是特别能理解 1234567891011121314151617181920212223242526class Solution {public: void duplicateZeros(vector<int>& arr) { int shift = 0; for(auto& num : arr) shift += (num == 0? 1 : 0); // i 是旧的arr的index, j是新的index int n = arr.size(); for (int i = n-1, j = n+shift-1; i < j; --i,--j) { if(arr[i] != 0) {。// 如果不是0 且 j 小于n了 那么就复制 if (j < n) arr[j] = arr[i]; }else{ // if (j < n){ // 如果是0 且j < n 那我们就让它为0 arr[j] = 0; } if (--j < n) { // 如果--j 小于n 那复制一遍0 arr[j] = 0; } } } }};]]></content>
<categories>
<category>Leetcode Easy</category>
<category>Array</category>
</categories>
<tags>
<tag>Leetcode</tag>
<tag>Array</tag>
<tag>review</tag>
</tags>
</entry>
<entry>
<title><![CDATA[566. Reshape the Matrix]]></title>
<url>%2F2019%2F12%2F07%2Fleetcode%2F566-Reshape-the-Matrix%2F</url>
<content type="text"><![CDATA[Answer1234567891011121314151617class Solution {public: vector<vector<int>> matrixReshape(vector<vector<int>>& nums, int r, int c) { int n = nums.size(), m = nums[0].size(); if (n*m != r*c) return nums; vector<vector<int>> res(r, vector<int>(c,0)); for(int i = 0; i < n; ++i) { for(int j = 0; j < m; ++j) { int index = i * m + j; res[index/c][index%c] = nums[i][j]; } } return res; }};]]></content>
<categories>
<category>Leetcode Easy</category>
<category>Array</category>
</categories>
<tags>
<tag>Leetcode</tag>
<tag>Array</tag>
</tags>
</entry>
<entry>
<title><![CDATA[243. Shortest Word Distance]]></title>
<url>%2F2019%2F12%2F06%2Fleetcode%2F243-Shortest-Word-Distance%2F</url>
<content type="text"><![CDATA[Answer123456789101112131415161718class Solution {public: int shortestDistance(vector<string>& words, string word1, string word2) { int word1Index = -1; int word2Index = -1; int res = INT_MAX; for (int i = 0; i < words.size(); ++i) { if (words[i] == word1) word1Index = i; if (words[i] == word2) word2Index = i; if (word1Index != -1 && word2Index != -1) { res = min(res, abs(word1Index-word2Index)); } } return res; }};]]></content>
<categories>
<category>Leetcode Easy</category>
<category>Array</category>
</categories>
<tags>
<tag>Leetcode</tag>
<tag>Array</tag>
</tags>
</entry>
<entry>
<title><![CDATA[1099. Two Sum Less Than K]]></title>
<url>%2F2019%2F12%2F03%2Fleetcode%2F1099-Two-Sum-Less-Than-K%2F</url>
<content type="text"><![CDATA[Answer 1这道题用暴力很容易做出来,复杂度是O(N^2)这边的思路是先排序,复杂度是(NlogN)然后双重循环来判定值,这边一个好处是如果和大于K就可以判断后面的值也用不着了。但是复杂度怎么说呢,也不知道。只知道比O(N^2)小。 1234567891011121314151617class Solution {public: int twoSumLessThanK(vector<int>& A, int K) { sort(A.begin(), A.end()); int res = -1; for(int i = 0; i < A.size(); ++i) { for (int j = i+1; j < A.size(); ++j) { int sum = A[i] + A[j]; if (sum < K) res = max(res, sum); else break; } } return res; }}; Answer 2最好还是双指针做吧 1234567891011121314151617181920class Solution {public: int twoSumLessThanK(vector<int>& A, int K) { sort(A.begin(), A.end()); int res = -1; int i = 0, j = A.size()-1; while( i < j) { int sum = A[i] + A[j]; if (sum < K) { res = max(res, sum); i++; }else j--; } return res; }};]]></content>
<categories>
<category>Leetcode Easy</category>
<category>Array</category>
</categories>
<tags>
<tag>Leetcode</tag>
<tag>Array</tag>
</tags>
</entry>
<entry>
<title><![CDATA[1150. Check If a Number Is Majority Element in a Sorted Array]]></title>
<url>%2F2019%2F12%2F03%2Fleetcode%2F1150-Check-If-a-Number-Is-Majority-Element-in-a-Sorted-Array%2F</url>
<content type="text"><![CDATA[Answer 1复杂度O(N) 很容易想到的一道题目 12345678910// 复杂度O(n)class Solution {public: bool isMajorityElement(vector<int>& nums, int target) { int res = 0; for(int& n: nums) res+= n == target ? 1 : 0; return res > nums.size()/2; }}; Answer 2因为有排序,复杂度变为O(logN) 1234567891011121314151617181920212223class Solution {public: bool isMajorityElement(vector<int>& nums, int target) { int res = 0; int i = 0, j = nums.size()-1; while(i <= j) { int mid = i + (j-i)/2; if (nums[mid] == target) { res++; int right = mid+1, left = mid-1; while(right < nums.size() && nums[right++] == target) res++; while(left >=0 && nums[left--] == target) res++; return res > nums.size()/2; } if (nums[mid] > target) j = mid-1; else i = mid+1; } return false; }};]]></content>
<categories>
<category>Leetcode Easy</category>
<category>Array</category>
</categories>
<tags>
<tag>Leetcode</tag>
<tag>Array</tag>
</tags>
</entry>
<entry>
<title><![CDATA[766. Toeplitz Matrix]]></title>
<url>%2F2019%2F11%2F29%2Fleetcode%2F766-Toeplitz-Matrix%2F</url>
<content type="text"><![CDATA[Answer 112345678910111213141516171819202122232425// 复杂度O(NM)class Solution {public: bool isToeplitzMatrix(vector<vector<int>>& matrix) { value = matrix[0][0]; for(int i = 0; i < matrix.size(); ++i) { int common = matrix[i][0]; if (!helper(matrix, i+1, 1, common)) return false; } for(int j = 0; j < matrix[0].size(); ++j) { int common = matrix[0][j]; if (!helper(matrix, 1, j+1, common)) return false; } return true; } bool helper(vector<vector<int>>& matrix, int i, int j, int& common) { if (i >= matrix.size() || j >= matrix[0].size()) return true; return (matrix[i][j] == common) && helper(matrix, i+1, j+1, common); }}; Answer 2第二种方法更简单,是在论坛找到的。很简洁 1234567891011121314151617// 复杂度O(NM)class Solution {public: bool isToeplitzMatrix(vector<vector<int>>& matrix) { int m = matrix.size(), n = matrix[0].size(); for(int i = 0; i < m-1; ++i) { for(int j = 0; j < n-1; ++j) { if (matrix[i][j] != matrix[i+1][j+1]) return false; } } return true; }};]]></content>
<categories>
<category>Leetcode Easy</category>
<category>Array</category>
</categories>
<tags>
<tag>Leetcode</tag>
<tag>Array</tag>
</tags>
</entry>
<entry>
<title><![CDATA[1266. Minimum Time Visiting All Points]]></title>
<url>%2F2019%2F11%2F28%2Fleetcode%2F1266-Minimum-Time-Visiting-All-Points%2F</url>
<content type="text"><![CDATA[Answer刚开始看起来还挺唬人的,以为要用BFS什么的做,没想到很简单 1234567891011121314// 复杂度O(N)class Solution {public: int minTimeToVisitAllPoints(vector<vector<int>>& points) { int res = 0; for (int i = 0; i < points.size()-1; ++i) { int hor = abs(points[i][0] - points[i+1][0]); int ver = abs(points[i][1] - points[i+1][1]); res += max(hor, ver); } return res; }}; [[36,59,71,15,26,82,87],[56,36,59,71,15,26,82],[15,0 ,36,59,71,15,26]]]]></content>
<categories>
<category>Leetcode Easy</category>
<category>Array</category>
</categories>
<tags>
<tag>Leetcode</tag>
<tag>Array</tag>
</tags>
</entry>
<entry>
<title><![CDATA[867. Transpose Matrix]]></title>
<url>%2F2019%2F11%2F28%2Fleetcode%2F867-Transpose-Matrix%2F</url>
<content type="text"><![CDATA[Answer傻瓜题目 123456789101112131415161718// 复杂度 O(N^2)class Solution {public: vector<vector<int>> transpose(vector<vector<int>>& A) { int n = A.size(), m = A[0].size(); vector<vector<int>> res(m, vector<int>(n,0)); for(int i = 0; i < n; ++i) { for(int j = 0; j < m; ++j) { res[j][i] = A[i][j]; } } return res; }};]]></content>
<categories>
<category>Leetcode Easy</category>
<category>Array</category>
</categories>
<tags>
<tag>Leetcode</tag>
<tag>Array</tag>
</tags>
</entry>
<entry>
<title><![CDATA[1002. Find Common Characters]]></title>
<url>%2F2019%2F11%2F22%2Fleetcode%2F1002-Find-Common-Characters%2F</url>
<content type="text"><![CDATA[Answer很多有字母相关的题目都可以塑造一个26长度的array来完成。 1234567891011121314151617181920class Solution {public: vector<string> commonChars(vector<string>& A) { vector<int> cnt(26, INT_MAX); for(auto& word: A) { vector<int> cnt0(26, 0); for(auto& c : word) cnt0[c - 'a']++; for(int i = 0; i < 26; ++i) cnt[i] = min(cnt[i], cnt0[i]); } vector<string> res; for(int i = 0; i < 26; ++i) { for(int j = 0; j < cnt[i]; ++j) res.push_back(string(1, 'a' + i)); } return res; }};]]></content>
<categories>
<category>Leetcode Easy</category>
<category>Array</category>
</categories>
<tags>
<tag>Leetcode</tag>
<tag>Array</tag>
</tags>
</entry>
<entry>
<title><![CDATA[1200. Minimum Absolute Difference]]></title>
<url>%2F2019%2F11%2F22%2Fleetcode%2F1200-Minimum-Absolute-Difference%2F</url>
<content type="text"><![CDATA[Answer看完觉得比较简单。但是感觉没什么挑战。又是亚麻的题目O.O 12345678910111213141516171819202122// 复杂度 O(NlogN)class Solution {public: vector<vector<int>> minimumAbsDifference(vector<int>& arr) { vector<vector<int>> res; sort(arr.begin(), arr.end()); // find the minimum value int minDist = INT_MAX; for(int i = 0; i < arr.size()-1; ++i) { minDist = min(minDist, arr[i+1] - arr[i]); } // return res for (int i = 0; i < arr.size()-1; ++i) { if (arr[i+1] - arr[i] == minDist) res.push_back(vector<int>{arr[i], arr[i+1]}); } return res; }};]]></content>
<categories>
<category>Leetcode Easy</category>
<category>Array</category>
</categories>
<tags>
<tag>Leetcode</tag>
<tag>Array</tag>
</tags>
</entry>
<entry>
<title><![CDATA[1122. Relative Sort Array]]></title>
<url>%2F2019%2F11%2F20%2Fleetcode%2F1122-Relative-Sort-Array%2F</url>
<content type="text"><![CDATA[Answer123456789101112131415161718192021222324class Solution {public: vector<int> relativeSortArray(vector<int>& arr1, vector<int>& arr2) { unordered_set<int> arr2Set(arr2.begin(), arr2.end()); vector<int> notExist; unordered_map<int, int> times; for(auto& num : arr1) { times[num]++; if (arr2Set.count(num) == 0) notExist.push_back(num); } sort(notExist.begin(), notExist.end()); vector<int> res; for(auto& num: arr2){ while(times[num]-- > 0) res.push_back(num); } for(auto& num: notExist) res.push_back(num); return res; }};]]></content>
<categories>
<category>Leetcode Easy</category>
<category>Array</category>
</categories>
<tags>
<tag>Leetcode</tag>
<tag>Array</tag>
</tags>
</entry>
<entry>
<title><![CDATA[1160. Find Words That Can Be Formed by Characters]]></title>
<url>%2F2019%2F11%2F20%2Fleetcode%2F1160-Find-Words-That-Can-Be-Formed-by-Characters%2F</url>
<content type="text"><![CDATA[Answer比较简单一道题,但是写的没有很爽。因为感觉逻辑有点混乱 1234567891011121314151617181920class Solution {public: int countCharacters(vector<string>& words, string chars) { // restore vector<int> record(26,0); for(auto& c: chars) record[c - 'a']++; int res = 0; for (auto& word : words) { int len = 0; vector<int> tmp = record; while(len < word.size() && tmp[word[len] - 'a'] > 0) { tmp[word[len++] - 'a']--; } if (len == word.length()) res+= len; } return res; }};]]></content>
<categories>
<category>Leetcode Easy</category>
<category>Array</category>
</categories>
<tags>
<tag>Leetcode</tag>
<tag>Array</tag>
</tags>
</entry>
<entry>
<title><![CDATA[509. Fibonacci Number]]></title>
<url>%2F2019%2F11%2F20%2Fleetcode%2F509-Fibonacci-Number%2F</url>
<content type="text"><![CDATA[Description经典的递归问题了 Answer 112345678910class Solution {public: int memo[31]; int fib(int N) { if (N == 0) return 0; if (N == 1) return 1; if (memo[N] == 0) memo[N] = fib(N-1) + fib(N-2); return memo[N]; }}; Answer 2123456789101112131415class Solution {public: int memo[31]; int fib(int N) { if (N <= 1) return N; int i = 0, j = 1; int sum = 0; while(N-- > 1) { sum = i + j; i = j; j = sum; } return sum; }};]]></content>
<categories>
<category>Leetcode Easy</category>
<category>Array</category>
</categories>
<tags>
<tag>Leetcode</tag>
<tag>Array</tag>
</tags>
</entry>
<entry>
<title><![CDATA[1133. Largest Unique Number]]></title>
<url>%2F2019%2F11%2F20%2Fleetcode%2F1133-Largest-Unique-Number%2F</url>
<content type="text"><![CDATA[Answer很简单的一道题目。用map来储存数据和出现的次数,然后便利判断就可以了不过似乎题目不够严谨,没有说一定都是大于0的数。因为在test case 是[-5 -6]的时候,出来的结果是-1显然不正确 1234567891011121314// 复杂度:O(N LogN)class Solution {public: int largestUniqueNumber(vector<int>& A) { unordered_map<int, int> map; for(auto& num : A) map[num]++; int res = INT_MIN; for(auto it: map) { if (it.second > 1) continue; res = max(it.first, res); } return res == INT_MIN ? -1 : res; }};]]></content>
<categories>
<category>Leetcode Easy</category>
<category>Array</category>
</categories>
<tags>
<tag>Leetcode</tag>
<tag>Array</tag>
</tags>
</entry>
<entry>
<title><![CDATA[922. Sort Array By Parity II]]></title>
<url>%2F2019%2F11%2F20%2Fleetcode%2F922-Sort-Array-By-Parity-II%2F</url>
<content type="text"><![CDATA[Answer两个指针。不过没想到哦 1234567891011121314class Solution {public: vector<int> sortArrayByParityII(vector<int>& A) { int odd = 0, even = 1, n = A.size(); while( odd< n && even < n) { while( odd <n && A[odd] %2 == 0) odd +=2; while( even <n && A[even]%2 == 1) even+=2; if (odd< n && even < n) swap(A[odd], A[even]); } return A; }};]]></content>
<categories>
<category>Leetcode Easy</category>
<category>Array</category>
</categories>
<tags>
<tag>Leetcode</tag>
<tag>Array</tag>
</tags>
</entry>
<entry>
<title><![CDATA[561. Array Partition I]]></title>
<url>%2F2019%2F11%2F17%2Fleetcode%2F561-Array-Partition-I%2F</url>
<content type="text"><![CDATA[Answer意外简单的一道题目。题目是说有2N个数字,需要组成N对数字,要求N对里面最小的数字加起来最大。所以应该是小的尽量要跟小的组一起,这样不会浪费大的数字。排序一下然后挑选各自最小的就ok了 12345678910111213// 时间复杂度O(NlogN)class Solution {public: int arrayPairSum(vector<int>& nums) { sort(nums.begin(), nums.end()); int res = 0; for(int i = 0; i < nums.size(); i = i + 2) { res += nums[i]; } return res; }};]]></content>
<categories>
<category>Leetcode Easy</category>
<category>Array</category>
</categories>
<tags>
<tag>Leetcode</tag>
<tag>Array</tag>
</tags>
</entry>
<entry>
<title><![CDATA[1064. Fixed Point]]></title>
<url>%2F2019%2F11%2F16%2Fleetcode%2F1064-Fixed-Point%2F</url>
<content type="text"><![CDATA[Answer 1第一种方法应该是最好想出来的,就是遍历数组然后找出i和A[i]相同的值,就是题目要求的最小的值。复杂度是O(N) 1234567891011class Solution {public: int fixedPoint(vector<int>& A) { for(int i = 0; i < A.size(); ++i) { if (i == A[i]) return i; } return -1; }}; Answer 2第二种方法是寻求O(logN)的二分查找法。A[i] < A[i+1]A[i] <= A[i+1] - 1A[i] - i <= A[i+1] - i - 1即 A[i] - i <= A[i+1] - (i +1)因此,题目可以变为查找A[i]-i中第一个数值为0的序列。 1234567891011121314151617class Solution {public: int fixedPoint(vector<int>& A) { int i = 0, j = A.size()-1; while(i < j) { int mid = i + (j - i) / 2; // 假如小于0, 那么目标一定是在右边 因此左边的一定是比0小的(右边有可能比0大的|等于0的)。 if (A[mid] - mid < 0) i = mid + 1; else j = mid; } return A[i] == i ? i : -1; }}; 思考这题的二分查找一个关键的思想在于,通过设定条件来判断答案是在左边,还是在非左边。 假设题目变为查找最大或者最后一个值那么代码应该变为 1234567891011121314151617class Solution {public: int fixedPoint(vector<int>& A) { int i = 0, j = A.size()-1; while(i < j) { int mid = i + (j - i) / 2; // 假如大于0, 那么目标一定是在左边 if (A[mid] - mid > 0) j = mid - 1; else i = mid; } return A[i] == i ? i : -1; }}; 是这样想的,但是无法实现会造成死循环]]></content>
<categories>
<category>Leetcode Easy</category>
<category>Array</category>
</categories>
<tags>
<tag>Leetcode</tag>
<tag>Array</tag>
<tag>Binary Search</tag>
</tags>
</entry>
<entry>
<title><![CDATA[977. Squares of a Sorted Array]]></title>
<url>%2F2019%2F11%2F15%2Fleetcode%2F977-Squares-of-a-Sorted-Array%2F</url>
<content type="text"></content>
<categories>
<category>Leetcode Easy</category>
<category>Array</category>
</categories>
<tags>
<tag>Leetcode</tag>
<tag>Array</tag>
</tags>
</entry>
<entry>
<title><![CDATA[905. Sort Array By Parity]]></title>
<url>%2F2019%2F11%2F13%2Fleetcode%2F905-Sort-Array-By-Parity%2F</url>
<content type="text"><![CDATA[Answer12345678910111213// 复杂度O(N)// in placeclass Solution {public: vector<int> sortArrayByParity(vector<int>& A) { for(int i = 0, j = 0; j < A.size(); ++j) { if (A[j] % 2 == 0) swap(A[j], A[i++]); } return A; }};]]></content>
<categories>
<category>Leetcode Easy</category>
<category>Array</category>
</categories>
<tags>
<tag>Leetcode</tag>
<tag>Array</tag>
</tags>
</entry>
<entry>
<title><![CDATA[832. Flipping an Image]]></title>
<url>%2F2019%2F11%2F12%2Fleetcode%2F832-Flipping-an-Image%2F</url>
<content type="text"><![CDATA[Answer12345678910111213141516171819202122// 复杂度: O(NM) N,M分别为行列数class Solution {public: vector<vector<int>> flipAndInvertImage(vector<vector<int>>& A) { int n = A.size(); int m = A[0].size(); for(int i = 0; i < n; ++i) { vector<int> tmpRow = A[i]; for(int j = 0; j < (m+1)/2; ++j) { swap(A[i][j], A[i][m-j-1]); } } for(int i = 0; i < n; ++i) { for(int j = 0; j < m; ++j) A[i][j] = 1 - A[i][j]; } return A; }};]]></content>
<categories>
<category>Leetcode Easy</category>
<category>Array</category>
</categories>
<tags>
<tag>Leetcode</tag>
<tag>Array</tag>
</tags>
</entry>
<entry>
<title><![CDATA[1085. Sum of Digits in the Minimum Number]]></title>
<url>%2F2019%2F11%2F11%2Fleetcode%2F1085-Sum-of-Digits-in-the-Minimum-Number%2F</url>
<content type="text"><![CDATA[Answer1234567891011121314151617// 复杂度O(N)class Solution {public: int sumOfDigits(vector<int>& A) { int minNum = INT_MAX; for(auto& num : A) minNum = min(num, minNum); int sum = 0; while(minNum > 0) { sum += minNum%10; minNum = minNum / 10; } return 1- sum%2; }}; Think好简单的一道题目,一看竟然是亚麻的,不可思议。这样不可以诶。不过今晚没时间了还是水一道题目去看其他的吧hope everything fine tomorrow.]]></content>
<categories>
<category>Leetcode Easy</category>
<category>Array</category>
</categories>
<tags>
<tag>Leetcode</tag>
<tag>Array</tag>
</tags>
</entry>
<entry>
<title><![CDATA[1086. High Five]]></title>
<url>%2F2019%2F11%2F10%2Fleetcode%2F1086-High-Five%2F</url>
<content type="text"><![CDATA[ProblemNote: Example Input:Output:Explanation: ExplanationAnswer12345678910111213141516171819202122232425262728293031// 思路:比较简单的一道题目// 创造一个map 来维护学生id和所有成绩// 使用pq来维护前五大成绩// 最后遍历pq来获得总和求得平均数// 复杂度: O(N) // 虽然pq的复杂度应该是O(NlongN),但是由于我们只维护了5个值,所以heap的深度是一定的class Solution {public: vector<vector<int>> highFive(vector<vector<int>>& items) { map<int, priority_queue<int, std::vector<int>, std::greater<int> >> map; for(auto& item: items) { map[item[0]].push(item[1]); if (map[item[0]].size() > 5) map[item[0]].pop(); } vector<vector<int>> res; for (auto& item: map) { int tmp = 0; while(!map[item.first].empty()) { tmp += map[item.first].top(); map[item.first].pop(); } res.push_back(vector<int>{item.first,tmp/5}); } return res; }};]]></content>
<categories>
<category>Leetcode Easy</category>
<category>Array</category>
</categories>
<tags>
<tag>Leetcode - Array</tag>