目录
977. Squares of a Sorted Array
刷题顺序
紫色表示已做
ID | Title |
---|---|
1 | Two Sum |
3 | Longest Substring Without Repeating Characters |
4 | Median of Two Sorted Arrays |
5 | Longest Palindromic Substring |
7 | Reverse Integer |
8 | String to Integer (atoi) |
10 | Regular Expression Matching |
11 | Container With Most Water |
12 | Integer to Roman |
13 | Roman to Integer |
15 | 3Sum |
17 | Letter Combinations of a Phone Number |
18 | 4Sum |
20 | Valid Parentheses |
22 | Generate Parentheses |
23 | Merge k Sorted Lists |
26 | Remove Duplicates from Sorted Array |
27 | Remove Element |
28 | Implement strStr() |
29 | Divide Two Integers |
31 | Next Permutation |
32 | Longest Valid Parentheses |
33 | Search in Rotated Sorted Array |
34 | Search for a Range |
35 | Search Insert Position |
36 | Valid Sudoku |
37 | Sudoku Solver |
38 | Count and Say |
39 | Combination Sum |
40 | Combination Sum II |
41 | First Missing Positive |
42 | Trapping Rain Water |
43 | Multiply Strings |
44 | Wildcard Matching |
45 | Jump Game II |
46 | Permutations |
47 | Permutations II |
48 | Rotate Image |
49 | Group Anagrams |
50 | Pow(x, n) |
51 | N-Queens |
52 | N-Queens II |
53 | Maximum Subarray |
54 | Spiral Matrix |
55 | Jump Game |
56 | Merge Intervals |
57 | Insert Interval |
59 | Spiral Matrix II |
60 | Permutation Sequence |
62 | Unique Paths |
64 | Minimum Path Sum |
65 | Valid Number |
66 | Plus One |
67 | Add Binary |
68 | Text Justification |
69 | Sqrt(x) |
70 | Climbing Stairs |
71 | Simplify Path |
72 | Edit Distance |
74 | Search a 2D Matrix |
75 | Sort Colors |
76 | Minimum Window Substring |
77 | Combinations |
78 | Subsets |
79 | Word Search |
80 | Remove Duplicates from Sorted Array II |
81 | Search in Rotated Sorted Array II |
82 | Remove Duplicates from Sorted List II |
84 | Largest Rectangle in Histogram |
85 | Maximal Rectangle |
88 | Merge Sorted Array |
90 | Subsets II |
91 | Decode Ways |
96 | Unique Binary Search Trees |
98 | Validate Binary Search Tree |
101 | Symmetric Tree |
104 | Maximum Depth of Binary Tree |
108 | Convert Sorted Array to Binary Search Tree |
110 | Balanced Binary Tree |
111 | Minimum Depth of Binary Tree |
112 | Path Sum |
113 | Path Sum II |
115 | Distinct Subsequences |
116 | Populating Next Right Pointers in Each Node |
117 | Populating Next Right Pointers in Each Node II |
121 | Best Time to Buy and Sell Stock |
122 | Best Time to Buy and Sell Stock II |
123 | Best Time to Buy and Sell Stock III |
124 | Binary Tree Maximum Path Sum |
125 | Valid Palindrome |
126 | Word Ladder II |
127 | Word Ladder |
128 | Longest Consecutive Sequence |
130 | Surrounded Regions |
133 | Clone Graph |
134 | Gas Station |
138 | Copy List with Random Pointer |
139 | Word Break |
140 | Word Break II |
142 | Linked List Cycle II |
146 | LRU Cache |
149 | Max Points on a Line |
150 | Evaluate Reverse Polish Notation |
152 | Maximum Product Subarray |
153 | Find Minimum in Rotated Sorted Array |
154 | Find Minimum in Rotated Sorted Array II |
155 | Min Stack |
157 | Read N Characters Given Read4 |
158 | Read N Characters Given Read4 II - Call multiple times |
161 | One Edit Distance |
162 | Find Peak Element |
163 | Missing Ranges |
168 | Excel Sheet Column Title |
171 | Excel Sheet Column Number |
173 | Binary Search Tree Iterator |
186 | Reverse Words in a String II |
174 | Dungeon Game |
188 | Best Time to Buy and Sell Stock IV |
189 | Rotate Array |
191 | Number of 1 Bits |
198 | House Robber |
200 | Number of Islands |
201 | Bitwise AND of Numbers Range |
202 | Happy Number |
204 | Count Primes |
205 | Isomorphic Strings |
207 | Course Schedule |
208 | Implement Trie (Prefix Tree) |
209 | Minimum Size Subarray Sum |
210 | Course Schedule II |
211 | Add and Search Word - Data structure design |
212 | Word Search II |
213 | House Robber II |
214 | Shortest Palindrome |
215 | Kth Largest Element in an Array |
216 | Combination Sum III |
217 | Contains Duplicate |
218 | The Skyline Problem |
219 | Contains Duplicate II |
220 | Contains Duplicate III |
221 | Maximal Square |
224 | Basic Calculator |
225 | Implement Stack using Queues |
226 | Invert Binary Tree |
227 | Basic Calculator II |
228 | Summary Ranges |
230 | Kth Smallest Element in a BST |
231 | Power of Two |
232 | Implement Queue using Stacks |
235 | Lowest Common Ancestor of a Binary Search Tree |
236 | Lowest Common Ancestor of a Binary Tree |
238 | Product of Array Except Self |
239 | Sliding Window Maximum |
240 | Search a 2D Matrix II |
241 | Different Ways to Add Parentheses |
242 | Valid Anagram |
244 | Shortest Word Distance II |
245 | Shortest Word Distance III |
249 | Group Shifted Strings |
251 | Flatten 2D Vector |
252 | Meeting Rooms |
253 | Meeting Rooms II |
254 | Factor Combinations |
256 | Paint House |
257 | Binary Tree Paths |
261 | Graph Valid Tree |
263 | Ugly Number |
264 | Ugly Number II |
265 | Paint House II |
268 | Missing Number |
269 | Alien Dictionary |
270 | Closest Binary Search Tree Value |
271 | Encode and Decode Strings |
273 | Integer to English Words |
274 | H-Index |
275 | H-Index II |
276 | Paint Fence |
277 | Find the Celebrity |
278 | First Bad Version |
279 | Perfect Squares |
280 | Wiggle Sort |
282 | Expression Add Operators |
283 | Move Zeroes |
284 | Peeking Iterator |
285 | Inorder Successor in BST |
286 | Walls and Gates |
287 | Find the Duplicate Number |
288 | Unique Word Abbreviation |
289 | Game of Life |
290 | Word Pattern |
291 | Word Pattern II |
293 | Flip Game |
294 | Flip Game II |
295 | Find Median from Data Stream |
296 | Best Meeting Point |
297 | Serialize and Deserialize Binary Tree |
298 | Binary Tree Longest Consecutive Sequence |
299 | Bulls and Cows |
300 | Longest Increasing Subsequence |
301 | Remove Invalid Parentheses |
302 | Smallest Rectangle Enclosing Black Pixels |
305 | Number of Islands II |
307 | Range Sum Query - Mutable |
308 | Range Sum Query 2D - Mutable |
309 | Best Time to Buy and Sell Stock with Cooldown |
311 | Sparse Matrix Multiplication |
312 | Burst Balloons |
314 | Binary Tree Vertical Order Traversal |
316 | Remove Duplicate Letters |
317 | Shortest Distance from All Buildings |
318 | Maximum Product of Word Lengths |
322 | Coin Change |
323 | Number of Connected Components in an Undirected Graph |
324 | Wiggle Sort II |
325 | Maximum Size Subarray Sum Equals k |
329 | Longest Increasing Path in a Matrix |
334 | Increasing Triplet Subsequence |
336 | Palindrome Pairs |
337 | House Robber III |
338 | Counting Bits |
339 | Nested List Weight Sum |
340 | Longest Substring with At Most K Distinct Characters |
341 | Flatten Nested List Iterator |
346 | Moving Average from Data Stream |
347 | Top K Frequent Elements |
348 | Design Tic-Tac-Toe |
350 | Intersection of Two Arrays II |
351 | Android Unlock Patterns |
352 | Data Stream as Disjoint Intervals |
353 | Design Snake Game |
354 | Russian Doll Envelopes |
355 | Design Twitter |
359 | Logger Rate Limiter |
361 | Bomb Enemy |
362 | Design Hit Counter |
364 | Nested List Weight Sum II |
367 | Valid Perfect Square |
374 | Guess Number Higher or Lower |
375 | Guess Number Higher or Lower II |
376 | Wiggle Subsequence |
377 | Combination Sum IV |
378 | Kth Smallest Element in a Sorted Matrix |
379 | Design Phone Directory |
380 | Insert Delete GetRandom O(1) |
381 | Insert Delete GetRandom O(1) - Duplicates allowed |
384 | Shuffle an Array |
385 | Mini Parser |
389 | Find the Difference |
394 | Decode String |
398 | Random Pick Index |
905. 按奇偶排序数组
题目描述:把数组中的偶数排在前面,奇数排在后面。
解法一:建立一个额外的数组,扫描两遍原始数组,第一遍先把偶数放进去,第二遍再把奇数放进去。
class Solution {
public int[] sortArrayByParity(int[] A) {
int[] ans = new int[A.length];
int t = 0;
for (int i = 0; i < A.length; ++i)
if (A[i] % 2 == 0)
ans[t++] = A[i];
for (int i = 0; i < A.length; ++i)
if (A[i] % 2 == 1)
ans[t++] = A[i];
return ans;
}
}
解法二:采用插入排序思想,
//伪代码
for( i = 0 to n ){
for( j = 0 to i ) {
if ( i 为偶, j 为奇) then swap( i , j);
}
}
test case:3 1 4 2
解法三:采用快排中的双指针思想。
for( i 从头到尾,j 从尾到头,直到 i 和 j 相遇){
如果 i 指向的数是奇数,j 指向的数为偶数,则交换这两个数。
如果 i 在中途遇到偶数 ,i++;
如果 j 在中途遇到奇数, j--;
}
class Solution {
public int[] sortArrayByParity(int[] A) {
int i = 0, j = A.length - 1;
while (i < j) {
if (A[i] % 2 > A[j] % 2) {
int tmp = A[i];
A[i] = A[j];
A[j] = tmp;
}
if (A[i] % 2 == 0) i++;
if (A[j] % 2 == 1) j--;
}
return A;
}
}
832. 翻转图像 【矩阵】
给定一个二进制矩阵
A
,我们想先水平翻转图像,然后反转图像并返回结果。水平翻转图片就是将图片的每一行都进行翻转,即逆序。例如,水平翻转
[1, 1, 0]
的结果是[0, 1, 1]
。反转图片的意思是图片中的
0
全部被1
替换,1
全部被0
替换。例如,反转[0, 1, 1]
的结果是[1, 0, 0]
。示例 1:
输入: [[1,1,0],[1,0,1],[0,0,0]] 输出: [[1,0,0],[0,1,0],[1,1,1]] 解释: 首先翻转每一行: [[0,1,1],[1,0,1],[0,0,0]]; 然后反转图片: [[1,0,0],[0,1,0],[1,1,1]]
示例 2:
输入: [[1,1,0,0],[1,0,0,1],[0,1,1,1],[1,0,1,0]] 输出: [[1,1,0,0],[0,1,1,0],[0,0,0,1],[1,0,1,0]] 解释: 首先翻转每一行: [[0,0,1,1],[1,0,0,1],[1,1,1,0],[0,1,0,1]]; 然后反转图片: [[1,1,0,0],[0,1,1,0],[0,0,0,1],[1,0,1,0]]
解题思路:运用位运算性质,a^1 相当于把a按位取反,先按位取反,后翻转位置。
class Solution {
public int[][] flipAndInvertImage(int[][] A) {
int C = A[0].length;
for (int[] row: A)
for (int i = 0; i < (C + 1) / 2; ++i) {
int tmp = row[i] ^ 1;
row[i] = row[C - 1 - i] ^ 1;
row[C - 1 - i] = tmp;
}
return A;
}
}
977. Squares of a Sorted Array
Given an array of integers
A
sorted in non-decreasing order, return an array of the squares of each number, also in sorted non-decreasing order.题目大意:给出一个排好序的数组,返回数组中每个数的平方数,并排好序。
Example 1:
Input: [-4,-1,0,3,10] Output: [0,1,9,16,100]
Example 2:
Input: [-7,-3,2,3,11] Output: [4,9,9,49,121]
解题思路:要利用好题目中数组已经有序这个已知条件,采用双指针法,并建立一个新数组。i 从头到尾,j从尾到头,i,j 中哪个数的绝对值大,那么意味着平方数就大,那么先把它的平方数放入新数组末端。大的那个就忘中间移动一位,小的那个就等待下一次的比较,如此进行,直到 i , j在中间相遇。
class Solution {
public int[] sortedSquares(int[] A) {
int n = A.length;
int[] result = new int[n];
int i = 0, j = n - 1;
for (int p = n - 1; p >= 0; p--) {
if (Math.abs(A[i]) > Math.abs(A[j])) {
result[p] = A[i] * A[i];
i++;
} else {
result[p] = A[j] * A[j];
j--;
}
}
return result;
}
}
922. 按奇偶排序数组 II【tag :矩阵】
给定一个非负整数数组
A
, A 中一半整数是奇数,一半整数是偶数。对数组进行排序,以便当
A[i]
为奇数时,i
也是奇数;当A[i]
为偶数时,i
也是偶数。你可以返回任何满足上述条件的数组作为答案。
示例:
输入:[4,2,5,7] 输出:[4,5,2,7] 解释:[4,7,2,5],[2,5,4,7],[2,7,4,5] 也会被接受。
思路:双指针法遍历数组,i遍历奇数位,j遍历偶数位,若奇数位的是偶数,偶数位的是奇数,则交换两个数。这里双指针法巧妙的将数组在逻辑上看成了两个数组。
class Solution {
public int[] sortArrayByParityII(int[] A) {
int i = 0, j = 1, n = A.length;
while (i < n && j < n) {
while (i < n && A[i] % 2 == 0) {
i += 2;
}
while (j < n && A[j] % 2 == 1) {
j += 2;
}
if (i < n && j < n) {
swap(A, i, j);
}
}
return A;
}
private void swap(int[] A, int i, int j) {
int temp = A[i];
A[i] = A[j];
A[j] = temp;
}
}
867. 转置矩阵
给定一个矩阵
A
, 返回A
的转置矩阵。矩阵的转置是指将矩阵的主对角线翻转,交换矩阵的行索引与列索引。
直接做法:
class Solution {
public int[][] transpose(int[][] A) {
int R = A.length, C = A[0].length;
int[][] ans = new int[C][R];
for (int r = 0; r < R; ++r)
for (int c = 0; c < C; ++c) {
ans[c][r] = A[r][c];
}
return ans;
}
}
优化:
如果输入的不是方阵,直接在原数组交换元素,则会导致数组越界。
public int[][] transpose(int[][] A) {
if (A.length == A[0].length) {
inPlace(A);
return A;
}
int[][] B = new int[A[0].length][A.length];
for (int i=0; i<A.length ; i++) {
for (int j=0; j<A[0].length ; j++) {
B[j][i] = A[i][j];
}
}
return B;
}
private void inPlace(int[][] A) {
int col = 0;
for (int i = 0; i<A.length ; i++) {
for (int j=col ; j<A[0].length ; j++) {
int temp = A[i][j];
A[i][j] = A[j][i];
A[j][i] = temp;
}
col++;
}
}
766. 托普利茨矩阵
判断一个矩阵中的每一条斜对角线上的数数否相等(左上到右下)。
输入: matrix = [ [1,2,3,4], [5,1,2,3], [9,5,1,2] ] 输出: True 解释: 在上述矩阵中, 其对角线为: "[9]", "[5, 5]", "[1, 1, 1]", "[2, 2, 2]", "[3, 3]", "[4]"。 各条对角线上的所有元素均相同, 因此答案是True。
这题一开始想复杂了。对于判断类型的题,可以采用先假定是这个类型,一旦不满足条件,直接返回false。先假设这个矩阵满足 托普利茨矩阵,遍历矩阵,如果遍历到的元素与左上角的元素不想等,则直接返回false。
class Solution {
public boolean isToeplitzMatrix(int[][] matrix) {
for (int r = 0; r < matrix.length; ++r)
for (int c = 0; c < matrix[0].length; ++c)
if (r > 0 && c > 0 && matrix[r-1][c-1] != matrix[r][c])
return false;
return true;
}
}
3. 无重复字符的最长子串
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是"abc",所以其
长度为 3。示例 2:
输入: "bbbbb" 输出: 1 解释: 因为无重复字符的最长子串是"b"
,所以其长度为 1。示例 3:
输入: "pwwkew" 输出: 3 解释: 因为无重复字符的最长子串是"wke"
,所以其长度为 3。 请注意,你的答案必须是 子串 的长度,"pwke"
是一个子序列,不是子串。
采用滑动窗口法,设置两个指针 i,j,其中j从前往后遍历,直到最后一个字符。i指向子串中j第一次出现的位置。滑动窗口其实是暴力算法的优化,暴力算法采用的策略是,i从前往后遍历,j从第i个位置开始遍历到最后一个位置,一次检查每个子串是否符合“无重复字符串”这个规定。
测试用例:
“abcabcbb"
1. 输出 abc j = 3, i = 1 res = j - i + 1=3
2. 输出 bca j = 4, i = 2 res = j - i + 1=3
(图像宽度:700,宽度:默认)
暴力算法:
public class Solution {
public int lengthOfLongestSubstring(String s) {
int n = s.length();
int ans = 0;
for (int i = 0; i < n; i++)
for (int j = i + 1; j <= n; j++)
if (allUnique(s, i, j)) ans = Math.max(ans, j - i);
return ans;
}
public boolean allUnique(String s, int start, int end) {
Set<Character> set = new HashSet<>();
for (int i = start; i < end; i++) {
Character ch = s.charAt(i);
if (set.contains(ch)) return false;
set.add(ch);
}
return true;
}
}
4. 寻找两个有序数组的中位数
给定两个大小为 m 和 n 的有序数组
nums1
和nums2
。请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n))。
你可以假设
nums1
和nums2
不会同时为空。示例 1:
nums1 = [1, 3] nums2 = [2] 则中位数是 2.0
示例 2:
nums1 = [1, 2] nums2 = [3, 4] 则中位数是 (2 + 3)/2 = 2.5
这个问题可以转换成:
将两个数组任意切两刀,假设数组被分成两部分记为,数组1 刀口的左边的元素计为 F1 ,右边的元素记为F2;数组2刀口的左边的元素计为 F3,右边的元素记为F4.
数组1:F1 | F2
数组2: F3 | F4
如果满足以下两个条件:
1. F1 + F3 的元素个数 = (数组1的长度 + 数组2的长度) / 2
2. F1整体小于F4 且 F2 整体小于F3
那么
把F1跟F3整合,会发现F1+F3就是将数组1和数组2放到一起的大数组中的二分刀口的左边部分,
同理,F2跟F4整合,就是刀口的右边部分
就可以说明 最终的中位数在F2的最左边和F3的最右边产生
好了,因为切的刀是任意的,那么现在要寻找这样的刀口满足上面的两个条件,因此采用二分查找的思想来找这样一个刀口。
通过不断的迭代,结果总是朝着解的方向前进。
class Solution {
public double findMedianSortedArrays(int[] A, int[] B) {
int m = A.length;
int n = B.length;
if (m > n) { // to ensure m<=n
int[] temp = A; A = B; B = temp;
int tmp = m; m = n; n = tmp;
}
int iMin = 0, iMax = m, halfLen = (m + n + 1) / 2;
while (iMin <= iMax) {
int i = (iMin + iMax) / 2;
int j = halfLen - i;
if (i < iMax && B[j-1] > A[i]){
iMin = i + 1; // i is too small
}
else if (i > iMin && A[i-1] > B[j]) {
iMax = i - 1; // i is too big
}
else { // i is perfect
int maxLeft = 0;
if (i == 0) { maxLeft = B[j-1]; }
else if (j == 0) { maxLeft = A[i-1]; }
else { maxLeft = Math.max(A[i-1], B[j-1]); }
if ( (m + n) % 2 == 1 ) { return maxLeft; }
int minRight = 0;
if (i == m) { minRight = B[j]; }
else if (j == n) { minRight = A[i]; }
else { minRight = Math.min(B[j], A[i]); }
return (maxLeft + minRight) / 2.0;
}
}
return 0.0;
}
}
7. 整数反转
给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转。
示例 1:
输入: 123 输出: 321
示例 2:
输入: -123 输出: -321
示例 3:
输入: 120 输出: 21
如果输入的x为整数的最大值2147483647,那么将它翻转后就会越界,因此要设res为long型
x % 10 表示取个位数
x / 10表示取除个位数以外的数
8. 字符串转换整数 (atoi)
示例 1:
输入: "42" 输出: 42
示例 2:
输入: " -42" 输出: -42 解释: 第一个非空白字符为 '-', 它是一个负号。 我们尽可能将负号与后面所有连续出现的数字组合起来,最后得到 -42 。
示例 3:
输入: "4193 with words" 输出: 4193 解释: 转换截止于数字 '3' ,因为它的下一个字符不为数字。
示例 4:
输入: "words and 987" 输出: 0 解释: 第一个非空字符是 'w', 但它不是数字或正、负号。 因此无法执行有效的转换。
示例 5:
输入: "-91283472332" 输出: -2147483648 解释: 数字 "-91283472332" 超过 32 位有符号整数范围。 因此返回 INT_MIN (−231) 。
public class StringtoInteger {
public int myAtoi(String str){
if(str == null || str.length() == 0) return 0;
str = str.trim();//去掉字符序列左边和右边的空格
char firstChar = str.charAt(0);
int sign = 1;
int start = 0;
long res = 0;
if(firstChar == '+'){
sign = 1;
start++;
} else if (firstChar == '-') {
sign = -1;
start++;
}
for (int i = start;i < str.length();i++){
if (!Character.isDigit(str.charAt(i))){
return (int) res * sign;
}
res = res * 10 + str.charAt(i) - '0';
if(sign == 1 && res > Integer.MAX_VALUE) return Integer.MAX_VALUE;
if(sign == -1 && res > Integer.MAX_VALUE) return Integer.MIN_VALUE;
}
return (int) res * sign;
}
}
10. 正则表达式匹配
给定一个字符串 (
s
) 和一个字符模式 (p
)。实现支持'.'
和'*'
的正则表达式匹配。'.' 匹配任意单个字符。 '*' 匹配零个或多个前面的元素。
匹配应该覆盖整个字符串 (
s
) ,而不是部分字符串。说明:
s
可能为空,且只包含从a-z
的小写字母。p
可能为空,且只包含从a-z
的小写字母,以及字符.
和*
。示例 1:
输入: s = "aa" p = "a" 输出: false 解释: "a" 无法匹配 "aa" 整个字符串。
示例 2:
输入: s = "aa" p = "a*" 输出: true 解释: '*' 代表可匹配零个或多个前面的元素, 即可以匹配 'a' 。因此, 重复 'a' 一次, 字符串可变为 "aa"。
示例 3:
输入: s = "ab" p = ".*" 输出: true 解释: ".*" 表示可匹配零个或多个('*')任意字符('.')。
示例 4:
输入: s = "aab" p = "c*a*b" 输出: true 解释: 'c' 可以不被重复, 'a' 可以被重复一次。因此可以匹配字符串 "aab"。
示例 5:
输入: s = "mississippi" p = "mis*is*p*." 输出: false
这题是二维DP问题,凡是两个字符串的匹配问题都可以转化为二维DP去做。
虽然是DP数组是二维的,但我们可以假想是由两个一维DP问题组合而成。
数组S: mississippi
数组P: mis*is*p*.
用i去遍历S数组,j去遍历P数组,那么可以得到如下的状态转移方程:
case1: 当 i.char == j.char 时,匹配成功,true状态往后移动,dp[i][j] = dp[i-1][j-1];
case2:当 j 的前一个字符是 “."时,可以匹配任何字符,同样的,true状态往后移动,dp[i][j] = dp[i-1][j-1];
case3: 如果j前一个字符是“*”,即 (j-1).char == “*”,那么判断 j 的前前个字符是否匹配成功 或者 是否是“." ,因为“."可以匹配任何字符。
如果是,那么dp[j] = dp[j-2]; 转换成二维的,就是dp[i][j] = dp[i][j-2];
如果不是,那么选择跳过 “*” 前面的字符,从dp[j-1] ,dp[j-2],dp[i-1]这三个状态选一个,其中dp[j-1]表示[0,j-2]这些字符串是匹配成功的.
比如:
下标 | 0 | 1 | 2 | 3 | 4 |
S数组(i) | d | a | a | a | a |
P数组(j) | e | a | * | c |
此时j == 3那么,dp[j-2] =dp[1] ==false; dp[j-1] == dp[2] == dp[1] == false;
class Solution {
public boolean isMatch(String s, String p) {
if(s == null || p == null) return false;
//定义状态
boolean[][] dp = new boolean[s.length() + 1][p.length() + 1];
//初始状态赋值
dp[0][0] = true;
for(int i=1; i<=s.length(); i++)
dp[i][0] = false;
for(int j=1; j<=p.length(); j++)
if(p.charAt(j-1) == '*' && dp[0][j-2])
dp[0][j] = true;
//利用初始状态值 以及 转移方程 求解未知状态值, 直到最终状态
for(int i=1; i<=s.length(); i++){
for(int j=1; j<=p.length(); j++){
//case 1
if(p.charAt(j-1) == s.charAt(i-1))
dp[i][j] = dp[i-1][j-1];
else if(p.charAt(j-1) == '.')
dp[i][j] = dp[i-1][j-1];
else if(p.charAt(j-1) == '*'){
if(p.charAt(j-2) != s.charAt(i-1) && p.charAt(j-2) != '.')
dp[i][j] = dp[i][j-2];
else
dp[i][j] = (dp[i][j-1] || dp[i-1][j] || dp[i][j-2]);
}else
dp[i][j] = false;
}
}
return dp[s.length()][p.length()];
}
}
(持续更新中。。。)