-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSolutionDemo.java
More file actions
1478 lines (1248 loc) · 44.1 KB
/
SolutionDemo.java
File metadata and controls
1478 lines (1248 loc) · 44.1 KB
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
package leetcode;
import java.util.*;
/**
* @author zhongshanhuang
* @company caih
* @email [email protected]
* @create 2019-10-24 18:53
*/
public class SolutionDemo {
public static void main(String[] args) {
// //2,两数之和
// ListNode listNode1 = new ListNode(5);
//// listNode1.next = new ListNode(4);
//// listNode1.next.next = new ListNode(3);
//
// ListNode listNode2 = new ListNode(5);
//// listNode2.next = new ListNode(6);
//// listNode2.next.next = new ListNode(4);
//
// Solution2 solution2 = new Solution2();
// ListNode listNodeResult = solution2.addTwoNumbers(listNode1, listNode2);
// System.out.println(listNodeResult.toString());
// //3,最长子串的长度
// Solution3 solution3 = new Solution3();
// System.out.println(solution3.lengthOfLongestSubstringBySet("abcabcbb"));
// System.out.println(solution3.lengthOfLongestSubstringByMap("abba")); //abba
// System.out.println(solution3.subOfLongestSubstringBySet("abba"));
// System.out.println(solution3.subOfLongestSubstringByMap("abba"));
//4, 寻找两数组的中位数
// Solution4 solution4 = new Solution4();
// System.out.println(solution4.findMedianSortedArrays(new int[]{1, 2, 3, 4}, new int[]{5, 6, 7, 8, 9}));
// //5,最长回文子串
// Solution5 solution5 = new Solution5();
// System.out.println(solution5.longestPalindromeByForce(""));
// System.out.println(solution5.longestPalindromeByDp1("babad"));
// //6,打印Z字形
// Solution6 solution6 = new Solution6();
// System.out.println(solution6.convert("LEETCODEISHIRING", 4));
// //7,反转整数
// Solution7 solution7 = new Solution7();
// System.out.println(solution7.reverse(1234567777));
// //8, 字符串转换整数 (atoi)
// Solution8 solution8 = new Solution8();
// System.out.println(solution8.myAtoi("words and 987"));
// //9,判断是否是回文数
// Solution9 solution9 = new Solution9();
// System.out.println(solution9.isPalindrome(12321));
// //11,盛最多水的容器
// Solution11 solution11 = new Solution11();
// System.out.println(solution11.maxArea(new int[]{1,8,6,2,5,4,8,3,7}));
// //12, 整数转罗马数字
// Solution12 solution12 = new Solution12();
// System.out.println(solution12.intToRoman(1994));
// //13, 罗马数字转整数
// Solution13 solution13 = new Solution13();
// System.out.println(solution13.romanToInt("LVIII"));
// //14. 最长公共前缀
// Solution14 solution14 = new Solution14();
// System.out.println(solution14.longestCommonPrefix(new String[]{"flower","flow","flight"}));
// //15, 三数之和
// Solution15 solution15 = new Solution15();
// System.out.println(solution15.threeSum(new int[]{-1, 0, 1, 2, -1, -4}));
// //16. 最接近的三数之和
// Solution16 solution16 = new Solution16();
// System.out.println(solution16.threeSumClosest(new int[]{-1, 2, 1, -4}, 1));
// //17. 电话号码的字母组合
// Solution17 solution17 = new Solution17();
// System.out.println(solution17.letterCombinations("234"));
// //20,有效的括号
// Solution20 solution20 = new Solution20();
// System.out.println(solution20.isValid("()[]{}"));
// //26. 删除排序数组中的重复项
// Solution26 solution26 = new Solution26();
// System.out.println(solution26.removeDuplicates(new int[]{0, 0, 1, 1, 1, 2, 2, 3, 3, 4}));
// //33,搜索旋转排序数组
// Solution33 solution33 = new Solution33();
// System.out.println(solution33.search(new int[] {4,5,6,7,0,1,2}, 0));
//34. 在排序数组中查找元素的第一个和最后一个位置
// Solution34 solution34 = new Solution34();
// int[] result = solution34.searchRange(new int[] {5,7,7,8,8,10}, 8);
// System.out.println(Arrays.toString(result));
// //39. 组合总和(可以无数次取)
// Solution39 solution39 = new Solution39();
// System.out.println(solution39.combinationSum(new int[]{2, 3, 6, 7}, 7));
//40,只可以取一次
// Solution40 solution40 = new Solution40();
// System.out.println(solution40.combinationSum2(new int[]{10,1,2,7,6,1,5}, 8));
//-------------------------------------------------------------------------
//-------------------------------------------------------------------------
// Solution557 solution557 = new Solution557();
// System.out.println(solution557.reverseWords("Let's take LeetCode contest"));
//238. 除自身以外数组的乘积
// Solution238 solution238 = new Solution238();
// System.out.println(Arrays.toString(solution238.productExceptSelf(new int[] {1,2,3,4})));
//42,接雨水
Solution42 solution42 = new Solution42();
System.out.println(solution42.trap(new int[]{0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1}));
// System.out.println(solution42.trap(new int[] {4,2,3}));
//字符串相乘
// Solution43 solution43 = new Solution43();
// System.out.println(solution43.multiply("123", "456"));
//49,生成旋转数组
// Solution59 solution59 = new Solution59();
// System.out.println(solution59.generateMatrix(3));
}
}
//2,两数之和-链表
class Solution2 {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
ListNode resultHead = null;
ListNode cur = null;
int carry = 0;
while (l1 != null || l2 != null) {
int x = (l1 == null ? 0 : l1.val);
int y = (l2 == null ? 0 : l2.val);
int sum = x + y + carry;
carry = sum / 10;
sum = sum % 10;
ListNode newListNode = new ListNode(sum);
if (null == resultHead) {
resultHead = newListNode;
cur = newListNode;
} else {
cur.next = newListNode;
cur = cur.next; //指向尾节点
}
if (null != l1) l1 = l1.next;
if (null != l2) l2 = l2.next;
}
//注意退出的时候要特别考虑
if (carry == 1) {
cur.next = new ListNode(1);
}
return resultHead;
}
}
class ListNode {
int val;
ListNode next;
ListNode(int x) {
val = x;
}
@Override
public String toString() {
return "ListNode{" +
"val=" + val +
", next=" + next +
'}';
}
}
/**
* 3,无重复字符的最长子串.如果改成输出最长子串呢?
*/
class Solution3 {
public int lengthOfLongestSubstringBySet(String s) {
//滑动窗口法:左边进行滑动,检查右边
Set<Character> set = new HashSet<>(); //易错Character,不是int!1
int len = s.length(); //易错2!
int result = 0, i = 0, j = 0; //result将被进行前后大小判断以迭代
while (i < len && j < len) {
if (!set.contains(s.charAt(j))) {
set.add(s.charAt(j++)); //添加完成之后才i++;
result = Math.max(result, j - i);
} else {
set.remove(i++);
}
}
return result;
}
public int lengthOfLongestSubstringByMap(String s) {
//滑动窗口法:左边进行滑动,检查右边
Map<Character, Integer> map = new HashMap<>(); //易错Character,不是int!1
int len = s.length(); //易错2!
int result = 0, i = 0, j = 0; //result将被进行前后大小判断以迭代
while (j < len) {
//map添加前判断,更新i
if (map.containsKey(s.charAt(j))) {
i = Math.max(map.get(s.charAt(j)), i); //易错!难点!形如abba时,当j轮到a时,避免i返回去取第一个a的值1
}
//一定添加
map.put(s.charAt(j++), j); //易错,这个地方将更新值,而键不变!“键数值位”
result = Math.max(result, j - i);
}
return result;
}
//获取最大子串
public String subOfLongestSubstringBySet(String s) {
//滑动窗口法:左边进行滑动,检查右边
Set<Character> set = new HashSet<>();
int[] indexs = new int[]{0, 0};
int len = s.length();
int difMax = 0, i = 0, j = 0;
while (i < len && j < len) {
if (!set.contains(s.charAt(j))) { //这里要等到i走到重复的字母前面才会停止。难点!
set.add(s.charAt(j++));
if ((j - i) > difMax) { //对当前的j进行操作,避免j++的影响
indexs[0] = i;
indexs[1] = j; //正好j+1,即在被截取的字符的后面
difMax = j - i;
}
} else {
set.remove(s.charAt(i++)); //为什么删除的是i++?因为要使得i的左边不包括在集合里
}
}
return s.substring(indexs[0], indexs[1]); //易错,substring含头不含尾(避开区间)
}
public String subOfLongestSubstringByMap(String s) {
//滑动窗口法:左边进行滑动,检查右边
Map<Character, Integer> map = new HashMap<>();
int[] indexs = new int[]{0, 0};
int len = s.length();
int difMax = 0, i = 0, j = 0;
while (j < len) {
if (map.containsKey(s.charAt(j))) {
i = Math.max(s.charAt(j), i);
}
map.put(s.charAt(j++), j);
if (j - i > difMax) {
difMax = j - i;
indexs[0] = i;
indexs[1] = j;
}
}
return s.substring(indexs[0], indexs[1]); //易错,substring含头不含尾(避开区间)
}
}
/**
* 5,最长回文子串
*/
class Solution5 {
//方法1:暴力法
public String longestPalindromeByForce(String s) {
int len = s.length();
String sSub = "";
String huiWenMax = "";
for (int i = 0; i < len; i++) {
for (int j = i + 1; j < len + 1; j++) {
sSub = s.substring(i, j);
if (isHuiWenString(sSub)) {
huiWenMax = sSub.length() > huiWenMax.length() ? sSub : huiWenMax;
}
}
}
return huiWenMax;
}
private boolean isHuiWenString(String s) {
int len = s.length();
for (int i = 0; i < len / 2; i++) {
if (s.charAt(i) != s.charAt(len - i - 1)) {
return false;
}
}
return true;
}
//方法2:动态规划法
public String longestPalindromeByDp1(String s) {
//动态规划2
//定义一个结构保存所有字串,存的是下标
class Str {
int i;
int j;
Str(int i, int j) {
this.i = i;
this.j = j;
}
}
//针对特殊情况进行处理
if (s.equals("") || s.length() == 1) {
return s;
}
//存储元回文串
ArrayList<Str> al = new ArrayList<>();
for (int i = 0; i < s.length(); i++) {
Str str = new Str(i, i);
al.add(str);
if (i != s.length() - 1) { //如果不是最后1个字符
//如果当前字符等于后一个字符,那么也要将该重复子串添加到单元数组中
if (s.charAt(i) == s.charAt(i + 1)) {
Str str2 = new Str(i, i + 1);
al.add(str2);
}
}
}
Str largeStr = new Str(0, 0); //存储最大
for (Str str : al) {
//向两边扩展
while (str.i != 0 && str.j != s.length() - 1) {
if (s.charAt(str.i - 1) == s.charAt(str.j + 1)) {
str.i--;
str.j++;
} else {
break;
}
}
//更新最大子串
if ((str.j - str.i) >= (largeStr.j - largeStr.i)) {
largeStr = str;
}
}
return s.substring(largeStr.i, largeStr.j + 1);
}
}
/**
* 6, Z字形变换
*/
class Solution6 {
public String convert(String s, int numRows) {
if (numRows < 2) {
return s;
}
List<StringBuilder> rows = new ArrayList<StringBuilder>();
//先放n个SB对象
for (int i = 0; i < numRows; i++) {
rows.add(new StringBuilder());
}
int i = 0, flag = -1;
//遍历字符串字符
for (char c : s.toCharArray()) {
rows.get(i).append(c);
if (i == 0 || i == numRows - 1) { //每一行的首位或者末位
flag = -flag;
}
i += flag;
}
StringBuilder res = new StringBuilder();
for (StringBuilder row : rows) {
res.append(row);
}
return res.toString();
}
}
/**
* 7,反转正数
*/
class Solution7 {
public int reverse(int x) {
int result = 0, a = 0;
while (x != 0) {
a = x % 10; // 得到最低位(除去低,百得低)
if (result > Integer.MAX_VALUE / 10 || ((Integer.MAX_VALUE / 10) == result && Integer.MAX_VALUE % 10 < a)) {
return 0; // 考虑溢出问题 数值范围 [-2^31, 2^31 - 1],Integer.MAX_VALUE % 10 < a 最后一位大于最大数的最后一位
}
if (result < Integer.MIN_VALUE / 10 || ((Integer.MAX_VALUE / 10) == result && Integer.MIN_VALUE % 10 > a)) {
return 0;
}
result = result * 10 + a;
x = x / 10;
}
return result;
}
}
/**
* 8, 字符串转换整数 (atoi)
*/
class Solution8 {
public int myAtoi(String str) {
if (str == null) {
return 0;
}
// 偷懒做法,去掉空格,也可以用while循环来做
String temp = str.trim();
if (temp.equals("") || temp.length() == 0) {
return 0;
}
//正数标记
boolean flag = true;
char[] bits = temp.toCharArray();
int i = 0;
int res = 0;
int bit = 0;
//负数标记
if (bits[0] == '-') {
flag = false;
}
//如果是符号位,那么就将i往后移一位
if (bits[0] == '+' || bits[0] == '-') {
i++;
}
for (; i < bits.length; i++) {
if (bits[i] >= '0' && bits[i] <= '9') { //如果是数字
bit = bits[i] - '0';
} else {
break; //如果为非数字,那么直接退出
}
// 这里巧妙的应用了如果溢出就取最大值 Integer.MAX_VALUE 或 Integer.MIN_VALUE,[-2147483648,2147483647]
if (res > Integer.MAX_VALUE / 10 || (res == Integer.MAX_VALUE / 10 && bit > 7)) {
return flag ? Integer.MAX_VALUE : Integer.MIN_VALUE;
}
res = res * 10 + bit;
}
return flag ? res : -res;
}
}
//9,判断是否是回文数
class Solution9 {
public boolean isPalindrome(int x) {
// 特殊情况:
// 如上所述,当 x < 0 时,x 不是回文数。
// 同样地,如果数字的最后一位是 0,为了使该数字为回文,
// 则其第一位数字也应该是 0
// 只有 0 满足这一属性
if (x < 0 || (x % 10 == 0 && x != 0)) {
return false;
}
int revertedNumber = 0;
while (x > revertedNumber) { //只循环到中位
revertedNumber = revertedNumber * 10 + x % 10;
x /= 10;
}
// 当数字长度为奇数时,我们可以通过 revertedNumber/10 去除处于中位的数字。
// 例如,当输入为 12321 时,在 while 循环的末尾我们可以得到 x = 12,revertedNumber = 123,
// 由于处于中位的数字不影响回文(它总是与自己相等),所以我们可以简单地将其去除。
return x == revertedNumber || x == revertedNumber / 10;
}
}
//11,盛最多水的容器
class Solution11 {
public int maxArea(int[] height) {
// int maxarea = 0;
// for (int i = 0; i < height.length; i++)
// for (int j = i + 1; j < height.length; j++)
// maxarea = Math.max(maxarea, Math.min(height[i], height[j]) * (j - i));
// return maxarea;
int maxarea = 0, l = 0, r = height.length - 1;
while (l < r) {
maxarea = Math.max(maxarea, Math.min(height[l], height[r]) * (r - l));
//谁的板子小则跳过谁
if (height[l] < height[r]) {
l++;
} else {
r--;
}
}
return maxarea;
}
}
//12, 整数转罗马数字
class Solution12 {
public String intToRoman(int num) {
// 把阿拉伯数字与罗马数字可能出现的所有情况和对应关系,放在两个数组中
// 并且按照阿拉伯数字的大小降序排列,这是贪心选择思想
int[] nums = {1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1};
String[] romans = {"M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"};
StringBuilder stringBuilder = new StringBuilder();
int index = 0;
while (index < 13) {
// 特别注意:这里是等号
while (num >= nums[index]) {
// 注意:这里是等于号,表示尽量使用大的"面值"
stringBuilder.append(romans[index]);
num -= nums[index];
}
index++;
}
return stringBuilder.toString();
}
}
//13. 罗马数字转整数
class Solution13 {
public int romanToInt(String s) {
Map<String, Integer> map = new HashMap<>();
map.put("I", 1);
map.put("IV", 4);
map.put("V", 5);
map.put("IX", 9);
map.put("X", 10);
map.put("XL", 40);
map.put("L", 50);
map.put("XC", 90);
map.put("C", 100);
map.put("CD", 400);
map.put("D", 500);
map.put("CM", 900);
map.put("M", 1000);
int ans = 0;
for (int i = 0; i < s.length(); ) {
if (i + 1 < s.length() && map.containsKey(s.substring(i, i + 2))) { //包含两个字符
ans += map.get(s.substring(i, i + 2));
i += 2;
} else { //只包含一个字符
ans += map.get(s.substring(i, i + 1));
i++;
}
}
return ans;
}
}
//14. 最长公共前缀
class Solution14 {
public String longestCommonPrefix(String[] strs) {
if (strs.length == 0)
return "";
String ans = strs[0]; //首先将第一个字符串进行初始化
for (int i = 1; i < strs.length; i++) { //遍历除了第一个字符串之后的所有剩余字符串
int j = 0;
//找到不相等的j值
for (; j < ans.length() && j < strs[i].length(); j++) {
if (ans.charAt(j) != strs[i].charAt(j))
break;
}
//获取共同子串
ans = ans.substring(0, j);
if (ans.equals("")) {
return ans;
}
}
return ans;
}
}
/**
* 15. 三数之和
*/
class Solution15 {
public List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> ans = new ArrayList();
int len = nums.length;
if (nums == null || len < 3) {
return ans;
}
Arrays.sort(nums); // 排序
for (int i = 0; i < len; i++) {
if (nums[i] > 0) {
break; // 如果当前数字大于0,则三数之和一定大于0,所以结束循环
}
if (i > 0 && nums[i] == nums[i - 1]) {
continue; // 去重
}
int L = i + 1;
int R = len - 1;
while (L < R) {
int sum = nums[i] + nums[L] + nums[R];
if (sum == 0) {
ans.add(Arrays.asList(nums[i], nums[L], nums[R]));
while (L < R && nums[L] == nums[L + 1]) {
L++; // 去重
}
while (L < R && nums[R] == nums[R - 1]) {
R--; // 去重
}
L++;
R--;
} else if (sum < 0) {
L++;
} else {
R--;
}
}
}
return ans;
}
}
/**
* 16. 最接近的三数之和
*/
class Solution16 {
public int threeSumClosest(int[] nums, int target) {
Arrays.sort(nums); //排序
int ans = nums[0] + nums[1] + nums[2];
for (int i = 0; i < nums.length; i++) {
int start = i + 1, end = nums.length - 1;
while (start < end) {
int sum = nums[start] + nums[end] + nums[i];
if (Math.abs(target - sum) < Math.abs(target - ans)) {
ans = sum;
}
//组目标是将sum变小,因数组有序,当sum > target时,说明sum很多,应将end--;反之,则将start++
if (sum > target) {
end--;
} else if (sum < target)
start++;
else {
return ans; //如果循环到最后,如果等于0,那么就将结果返回
}
}
}
return ans;
}
}
/**
* 17. 电话号码的字母组合
*/
class Solution17 {
Map<String, String> phone = new HashMap<String, String>() {{
put("2", "abc");
put("3", "def");
put("4", "ghi");
put("5", "jkl");
put("6", "mno");
put("7", "pqrs");
put("8", "tuv");
put("9", "wxyz");
}};
List<String> output = new ArrayList<String>();
public List<String> letterCombinations(String digits) {
if (digits.length() != 0)
backtrack("", digits);
return output;
}
private void backtrack(String combination, String next_digits) {
//回溯组合
if (next_digits.length() == 0) {
output.add(combination);
} else {
String digit = next_digits.substring(0, 1);
String letters = phone.get(digit);
for (int i = 0; i < letters.length(); i++) {
String letter = phone.get(digit).substring(i, i + 1); //分别取每一个字符
//next_digits.substring(1)。递归到最后一位数字,然后再回溯组合在一起
backtrack(combination + letter, next_digits.substring(1));
}
}
}
}
/**
* 19. 删除链表的倒数第N个节点
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution19 {
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode first = head;
ListNode second = head;
//移动n位
for (int i = 0; i < n; i++) {
second = second.next;
}
if (null == second) { //如果是null == second,说明删除的是头结点,特殊处理
head = head.next;
return head; //注意要返回
} else {
while (second.next != null) {
first = first.next;
second = second.next;
}
first.next = first.next.next; //是first.next = ...,而不是first = ...
return head;
}
}
//内部类
class ListNode {
int val;
ListNode next;
ListNode(int x) {
val = x;
}
}
}
/**
* 20,有效的括号
*/
class Solution20 {
private final Map<Character, Character> map = new HashMap<Character, Character>() {{
put('{', '}');
put('[', ']');
put('(', ')');
put('?', '?');
}};
public boolean isValid(String s) {
if (s.length() > 0 && !map.containsKey(s.charAt(0))) {
return false;
}
Stack<Character> stack = new Stack<>();
stack.add('?');
//策略,进来一个弹出一个进行判断,最后如果只剩下一个?,那么就是真括号
for (Character c : s.toCharArray()) { //最后不会进来?
if (map.containsKey(c)) {
stack.add(c);
} else if (map.get(stack.pop()) != c) {
return false;
}
}
return stack.size() == 1;
}
}
/**
* 21,leetCode上面给的算法其实没有封装好List类,但是提供了Node节点的定义,List类应该定义一个头节点
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution21 {
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
ListNode head1 = l1;
ListNode head2 = l2;
ListNode newHead = null;
ListNode cur = null;
if (null == l1 && null == l2) {
return null;
}
if (null == l1) {
return l2;
}
if (null == l2) {
return l1;
}
//将头节点指向最小的那个链表
if (head1.val < head2.val) {
newHead = head1;
cur = head1;
head1 = head1.next;
} else {
newHead = head2;
cur = head2;
head2 = head2.next;
}
while (head1 != null && head2 != null) {
if (head1.val < head2.val) {
cur.next = head1;
cur = cur.next;
head1 = head1.next;
} else {
cur.next = head2;
cur = cur.next;
head2 = head2.next;
}
}
cur.next = head1 == null ? head2 : head1;
return newHead;
}
}
/**
* 24. 两两交换链表中的节点
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution24 {
public ListNode swapPairs(ListNode head) {
ListNode pre = new ListNode(0);
pre.next = head;
ListNode temp = pre;
while (temp.next != null && temp.next.next != null) {
ListNode start = temp.next; //要交换的前节点
ListNode end = temp.next.next; //要交换的后节点
temp.next = end;
start.next = end.next;
end.next = start;
temp = start;
}
return pre.next;
}
}
/**
* 26. 删除排序数组中的重复项
*/
class Solution26 {
public int removeDuplicates(int[] nums) {
if (nums.length == 0) {
return 0;
}
int first = 0;
//不重复就放左边
for (int second = 1; second < nums.length; second++) {
//如果不相等,就更新慢指针,同时在慢指针处插入新值,慢指针同时还起到计数的作用
if (nums[second] != nums[first]) {
first++;
nums[first] = nums[second]; //因为前几个元素存储不重复的数字
}
}
return first + 1;
}
}
/**
* 27. 移除元素
*/
class Solution27 {
public int removeElement(int[] nums, int val) {
if (nums.length == 0) {
return 0;
}
int left = 0;
//不等就放左边
for (int right = 0; right < nums.length; right++) {
if (nums[right] != val) {
nums[left] = nums[right];
left++;
}
}
return left;
}
}
/**
* 28,实现 strStr(),判断是否存在子串
*/
class Solution28 {
public int strStr(String haystack, String needle) {
int lenH = haystack.length();
int lenN = needle.length();
for (int i = 0; i < lenH - lenN + 1; i++) {
if (haystack.substring(i, i + lenN).equals(needle)) {
return i;
}
}
return -1;
}
}
/**
* 33, 搜索旋转排序数组
*/
class Solution33 {
public int search(int[] nums, int target) {
if (nums == null || nums.length == 0) {
return -1;
}
int start = 0;
int end = nums.length - 1;
int mid;
while (start <= end) {
mid = (start + end) / 2;
if (nums[mid] == target) {
return mid;
}
//前半部分有序,注意此处用小于等于
if (nums[start] <= nums[mid]) {
//target在前半部分
if (target >= nums[start] && target < nums[mid]) {
end = mid - 1;
} else {
start = mid + 1;
}
} else {
if (target <= nums[end] && target > nums[mid]) {