0%

algorithm-pointer

简单

验证回文串

题目描述

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
如果在将所有大写字符转换为小写字符、并移除所有非字母数字字符之后,短语正着读和反着读都一样。则可以认为该短语是一个 回文串 。

字母和数字都属于字母数字字符。

给你一个字符串 s,如果它是 回文串 ,返回 true ;否则,返回 false 。



示例 1:

输入: s = "A man, a plan, a canal: Panama"
输出:true
解释:"amanaplanacanalpanama" 是回文串。
示例 2:

输入:s = "race a car"
输出:false
解释:"raceacar" 不是回文串。
示例 3:

输入:s = " "
输出:true
解释:在移除非字母数字字符之后,s 是一个空字符串 "" 。
由于空字符串正着反着读都一样,所以是回文串。


提示:

1 <= s.length <= 2 * 105
s 仅由可打印的 ASCII 字符组成

题目解答

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
public class Solution {
public boolean isPalindrome(String s) {
int i = 0;
int j = s.length() - 1;
while (i < j) {
// 也可以使用Character.isLetterOrDigit
while (i < j && !isAlphaNum(s.charAt(i))) {
i++;
}

// 也可以使用Character.isLetterOrDigit
while (i < j && !isAlphaNum(s.charAt(j))) {
j--;
}

if (i >= j) {
break;
}

// 也可以使用Character.toLowerCase
if (toLowerCase(s.charAt(i)) != toLowerCase(s.charAt(j))) {
return false;
}

i++;
j--;
}

return true;
}

private boolean isAlphaNum(char c) {
if (c >= '0' && c <= '9') {
return true;
} else if (c >= 'a' && c <= 'z') {
return true;
} else if (c >= 'A' && c <= 'Z') {
return true;
}

return false;
}

private char toLowerCase(char c) {
if (c >= 'A' && c <= 'Z') {
c = (char) (c + ('a' - 'A'));
}

return c;
}

public static void main(String[] args) {
testCase1();
testCase2();
testCase3();
}

public static void testCase1() {
String s = "A man, a plan, a canal: Panama";

boolean result = new Solution().isPalindrome(s);
System.out.println(result);
}

public static void testCase2() {
String s = "race a car";

boolean result = new Solution().isPalindrome(s);
System.out.println(result);
}

public static void testCase3() {
String s = " ";

boolean result = new Solution().isPalindrome(s);
System.out.println(result);
}
}

判断子序列

题目描述

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
给定字符串 s 和 t ,判断 s 是否为 t 的子序列。

字符串的一个子序列是原始字符串删除一些(也可以不删除)字符而不改变剩余字符相对位置形成的新字符串。(例如,"ace"是"abcde"的一个子序列,而"aec"不是)。

进阶:

如果有大量输入的 S,称作 S1, S2, ... , Sk 其中 k >= 10亿,你需要依次检查它们是否为 T 的子序列。在这种情况下,你会怎样改变代码?

致谢:

特别感谢 @pbrother 添加此问题并且创建所有测试用例。



示例 1:

输入:s = "abc", t = "ahbgdc"
输出:true
示例 2:

输入:s = "axc", t = "ahbgdc"
输出:false


提示:

0 <= s.length <= 100
0 <= t.length <= 10^4
两个字符串都只由小写字符组成。

题目解答

  • 双指针
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
public class Solution {
public boolean isSubsequence(String s, String t) {
int n = s.length(), m = t.length();
int i = 0, j = 0;
while (i < n && j < m) {
if (s.charAt(i) == t.charAt(j)) {
i++;
}
j++;
}
return i == n;
}

public static void main(String[] args) {
testCase1();
testCase2();
}

public static void testCase1() {
String s = "abc";
String t = "ahbgdc";

boolean result = new Solution().isSubsequence(s, t);
System.out.println(result);
}

public static void testCase2() {
String s = "axc";
String t = "ahbgdc";

boolean result = new Solution().isSubsequence(s, t);
System.out.println(result);
}
}

两数之和II

题目描述

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
给你一个下标从 1 开始的整数数组 numbers ,该数组已按 非递减顺序排列  ,请你从数组中找出满足相加之和等于目标数 target 的两个数。如果设这两个数分别是 numbers[index1] 和 numbers[index2] ,则 1 <= index1 < index2 <= numbers.length 。

以长度为 2 的整数数组 [index1, index2] 的形式返回这两个整数的下标 index1 和 index2。

你可以假设每个输入 只对应唯一的答案 ,而且你 不可以 重复使用相同的元素。

你所设计的解决方案必须只使用常量级的额外空间。


示例 1:

输入:numbers = [2,7,11,15], target = 9
输出:[1,2]
解释:2 与 7 之和等于目标数 9 。因此 index1 = 1, index2 = 2 。返回 [1, 2] 。
示例 2:

输入:numbers = [2,3,4], target = 6
输出:[1,3]
解释:2 与 4 之和等于目标数 6 。因此 index1 = 1, index2 = 3 。返回 [1, 3] 。
示例 3:

输入:numbers = [-1,0], target = -1
输出:[1,2]
解释:-1 与 0 之和等于目标数 -1 。因此 index1 = 1, index2 = 2 。返回 [1, 2] 。


提示:

2 <= numbers.length <= 3 * 104
-1000 <= numbers[i] <= 1000
numbers 按 非递减顺序 排列
-1000 <= target <= 1000
仅存在一个有效答案

题目解答

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
public class Solution {
public int[] twoSum(int[] numbers, int target) {
int i = 0;
int j = numbers.length - 1;

while (i < j) {
if (numbers[i] + numbers[j] < target) {
i++;
} else if (numbers[i] + numbers[j] > target) {
j--;
} else {
return new int[] { i + 1, j + 1 };
}
}

return new int[] { -1, -1 };
}

public static class ArrayUtils {
public static void printArray(int[] array) {
System.out.println(java.util.Arrays.toString(array));
}

public static void printArray(int[] array, int len) {
System.out.println(java.util.Arrays.toString(java.util.Arrays.copyOf(array, len)));
}

public static void printArrays(int[][] arrays) {
System.out.println(java.util.Arrays.deepToString(arrays));
}

public static void printArray(Integer[] array) {
System.out.println(java.util.Arrays.toString(array));
}

public static void printArray(Integer[] array, int len) {
System.out.println(java.util.Arrays.toString(java.util.Arrays.copyOf(array, len)));
}

public static void printArrays(Integer[][] arrays) {
System.out.println(java.util.Arrays.deepToString(arrays));
}

public static void printArray(String[] array) {
System.out.println(java.util.Arrays.toString(array));
}

public static void printArray(String[] array, int len) {
System.out.println(java.util.Arrays.toString(java.util.Arrays.copyOf(array, len)));
}

public static void printArrays(String[][] arrays) {
System.out.println(java.util.Arrays.deepToString(arrays));
}
}

public static void main(String[] args) {
testCase1();
testCase2();
testCase3();
}

public static void testCase1() {
int[] numbers = { 2, 7, 11, 15 };
int target = 9;

int[] result = new Solution().twoSum(numbers, target);
ArrayUtils.printArray(result);
}

public static void testCase2() {
int[] numbers = { 2, 3, 4 };
int target = 6;

int[] result = new Solution().twoSum(numbers, target);
ArrayUtils.printArray(result);
}

public static void testCase3() {
int[] numbers = { -1, 0 };
int target = -1;

int[] result = new Solution().twoSum(numbers, target);
ArrayUtils.printArray(result);
}
}

盛最多水的容器

题目描述

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
给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。

找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。

返回容器可以储存的最大水量。

说明:你不能倾斜容器。



示例 1:

输入:[1,8,6,2,5,4,8,3,7]
输出:49
解释:图中垂直线代表输入数组 [1,8,6,2,5,4,8,3,7]。在此情况下,容器能够容纳水(表示为蓝色部分)的最大值为 49。

示例 2:

输入:height = [1,1]
输出:1


提示:

n == height.length
2 <= n <= 105
0 <= height[i] <= 104

题目解答

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class Solution {
public int maxArea(int[] height) {
int l = 0, r = height.length - 1;
int ans = 0;
while (l < r) {
int area = Math.min(height[l], height[r]) * (r - l);
ans = Math.max(ans, area);
if (height[l] <= height[r]) {
++l;
} else {
--r;
}
}
return ans;
}
}

三数之和

题目描述

1
2
3
4
5
给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != j、i != k 且 j != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。请

你返回所有和为 0 且不重复的三元组。

注意:答案中不可以包含重复的三元组。

题目解答

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
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Solution {
public List<List<Integer>> threeSum(int[] nums) {
Arrays.sort(nums);

List<List<Integer>> result = new ArrayList<List<Integer>>();

int k = 0;
while (k < nums.length) {

int target = -nums[k];
int i = k + 1;
int j = nums.length - 1;

while (i < j) {
if (nums[i] + nums[j] > target) {
j--;
// 跳过重复元素
while (nums[j] == nums[j + 1] && i < j) {
j--;
}
} else if (nums[i] + nums[j] < target) {
i++;
// 跳过重复元素
while (nums[i] == nums[i - 1] && i < j) {
i++;
}
} else {
List<Integer> list = new ArrayList<Integer>();

list.add(nums[k]);
list.add(nums[i]);
list.add(nums[j]);

result.add(list);

i++;
// 跳过重复元素
while (nums[i] == nums[i - 1] && i < j) {
i++;
}

j--;
// 跳过重复元素
while (nums[j] == nums[j + 1] && i < j) {
j--;
}
}
}

k++;
// 跳过重复元素
while (k < nums.length && nums[k] == nums[k - 1]) {
k++;
}
}

return result;
}

public static class ListUtils {
public static void printList(java.util.List<? extends Object> list) {
System.out.println(java.util.Arrays.toString(list.toArray(new Object[0])));
}

public static void printLines(java.util.List<? extends Object> list) {
if (list == null) {
return;
}

for (Object o : list) {
System.out.println(o);
}
System.out.println();
}

public static void printLists1(java.util.List<java.util.List<Integer>> lists) {
Object[] arrays = new Object[lists.size()];
for (int i = 0; i < lists.size(); i++) {
arrays[i] = lists.get(i).toArray(new Object[0]);
}

System.out.println(java.util.Arrays.deepToString(arrays));
}

public static void printLists2(java.util.List<java.util.List<Double>> lists) {
Object[] arrays = new Object[lists.size()];
for (int i = 0; i < lists.size(); i++) {
arrays[i] = lists.get(i).toArray(new Object[0]);
}

System.out.println(java.util.Arrays.deepToString(arrays));
}

public static void printLists3(java.util.List<java.util.List<String>> lists) {
Object[] arrays = new Object[lists.size()];
for (int i = 0; i < lists.size(); i++) {
arrays[i] = lists.get(i).toArray(new Object[0]);
}

System.out.println(java.util.Arrays.deepToString(arrays));
}
}

public static void main(String[] args) {
testCase1();
testCase2();
testCase3();
}

public static void testCase1() {
int[] nums = { -1, 0, 1, 2, -1, -4 };

List<List<Integer>> result = new Solution().threeSum(nums);
ListUtils.printLists1(result);
}

public static void testCase2() {
int[] nums = { 0, 1, 1 };

List<List<Integer>> result = new Solution().threeSum(nums);
ListUtils.printLists1(result);
}

public static void testCase3() {
int[] nums = { 0, 0, 0 };

List<List<Integer>> result = new Solution().threeSum(nums);
ListUtils.printLists1(result);
}
}

困难

只想买包辣条