Skip to content

Commit 8581be1

Browse files
committed
Palindrome
Palindrome
1 parent 9b6e832 commit 8581be1

File tree

6 files changed

+443
-189
lines changed

6 files changed

+443
-189
lines changed

Diff for: BackTracking/README.md

+1-21
Original file line numberDiff line numberDiff line change
@@ -60,26 +60,6 @@ I failed the test case: "2001:0db8:85a3:0:0:8A2E:0370:7334:". The issue here is
6060
The java file contains solutions to leetcode question about
6161
palindrome. Some of the problems use backtracking.
6262

63-
## 131. Palindrome Partitioning (Medium) *
64-
Given a string s, partition s such that every substring of the partition is a palindrome.
65-
66-
Return all possible palindrome partitioning of s.
67-
68-
For example, given s = "aab",
69-
Return
70-
~~~~
71-
[
72-
["aa","b"],
73-
["a","a","b"]
74-
]
75-
~~~~
76-
77-
#### Solution
78-
Use backtracking template.
79-
1. Given a string s, if s.substring(0, i) is a valid palindrome, then recursively check the palindrome partition of s.substring(i).
80-
2. The base case of recursion is when a string is empty, we can add the partitions to final result and return.
81-
3. Handle the base return case carefully.
82-
8363
## 132. Palindrome Partitioning II (Hard) * (Backtracking exceed time limit)
8464
Given a string s, partition s such that every substring of the partition is a palindrome.
8565

@@ -177,7 +157,7 @@ It takes O(n) to get the solution. The code to build KMP table is kind of compli
177157
###### Solution 2
178158
Recursively check the longest palindrome substring from 0.
179159
Starting from the char in mid of the array.
180-
The time complexity n/2 + (n/2 - 1) + (n/2 - 2) + ... + (n/2 - n/2) = n/2 * n/2 - (n/4 + n^2/8) = O(n^2)
160+
The time complexity n/2 + (n/2 - 1) + (n/2 - 2) + ... + (n/2 - n/2) = n/2 * n/2 - (n/4 + n^2/8) = O(n^2)
181161

182162
## 266. Palindrome Permutation (Easy) *
183163
Given a string, determine if a permutation of the string could form a palindrome.

Diff for: String/Palindrome.md

+140
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,58 @@ public class Solution {
3636
}
3737
~~~
3838

39+
## 5. Longest Palindromic Substring
40+
Given a string s, find the longest palindromic substring in s. You may assume that the maximum length of s is 1000.
41+
42+
Example:
43+
~~~
44+
Input: "babad"
45+
Output: "bab"
46+
Note: "aba" is also a valid answer.
47+
~~~
48+
49+
Example:
50+
~~~
51+
Input: "cbbd"
52+
Output: "bb"
53+
~~~
54+
55+
#### Solution
56+
1. O(n^2) 每个节点作为中间点往两边搜索
57+
2. Manacher’s Algorithm O(n) Solution 可做做到O(n)
58+
59+
Time O(n^2) <br>
60+
~~~
61+
public class Solution {
62+
public String longestPalindrome(String s) {
63+
if (s == null || s.length() == 0) return s;
64+
String ans = "";
65+
66+
for (int i = 0; i < s.length(); i++) {
67+
String m = helper(s, i, i);
68+
String n = helper(s, i, i + 1);
69+
if (m.length() > ans.length()) ans = m;
70+
if (n.length() > ans.length()) ans = n;
71+
}
72+
73+
return ans;
74+
}
75+
76+
private String helper(String s, int start, int end) {
77+
int i = start;
78+
int j = end;
79+
while (i >= 0 && j < s.length()) {
80+
if (s.charAt(i) != s.charAt(j)) {
81+
break;
82+
}
83+
i--;
84+
j++;
85+
}
86+
return s.substring(i + 1, j);
87+
}
88+
}
89+
~~~
90+
3991
## 131. Palindrome Partitioning (Medium) *
4092
Given a string s, partition s such that every substring of the partition is a palindrome.
4193

@@ -104,3 +156,91 @@ public class Solution {
104156
}
105157
}
106158
~~~
159+
160+
## 132. Palindrome Partitioning II (Hard) *
161+
Given a string s, partition s such that every substring of the partition is a palindrome.
162+
163+
Return the minimum cuts needed for a palindrome partitioning of s.
164+
165+
For example, given s = "aab",
166+
Return 1 since the palindrome partitioning ["aa","b"] could be produced using 1 cut.
167+
168+
#### Solution
169+
1. 最笨的DP,if (s[j:i] is palindrome) DP[i] = dp[j] + 1, i和j有n^2个可能性,每次判断if (s[j:i] is palindrome)需要O(n)的时间,总耗时O(n^3), 不出意料TLE, 如何加快速度
170+
2. 可以提前计算一个palindrome lookup table, if (s[i] == s[j]) pal[i][j] = p[i+1][j-1]. **注意2维循环的时候i从高位到低位,j从低位到高位**,这样可以提高速度到O(n^2)
171+
3. Discussion top solution 给出了O(n^2) time, O(n) space的方法
172+
173+
Attempt: 没有想出O(n^2)的方法
174+
~~~
175+
public class Solution {
176+
public int minCut(String s) {
177+
if (s == null || s.length() == 0) return 0;
178+
179+
int len = s.length();
180+
181+
// pre-calculate the palindrom look-up table
182+
boolean[][] palindrome = new boolean[len][len];
183+
for (int i = len - 1; i >= 0; i--) {
184+
for (int j = i; j < len; j++) {
185+
if (s.charAt(i) == s.charAt(j)) {
186+
if (j - i < 2) {
187+
palindrome[i][j] = true;
188+
}
189+
else {
190+
palindrome[i][j] = palindrome[i + 1][j - 1];
191+
}
192+
}
193+
}
194+
}
195+
196+
int[] dp = new int[len];
197+
198+
for (int i = 0; i < len; i++) {
199+
dp[i] = i; // dp[0] = 0
200+
for (int j = i; j >= 0; j--) {
201+
if (palindrome[j][i]) {
202+
if (j == 0) dp[i] = 0;
203+
else dp[i] = Math.min(dp[i], dp[j - 1] + 1);
204+
}
205+
}
206+
}
207+
208+
return dp[len - 1];
209+
}
210+
}
211+
~~~
212+
213+
## 266. Palindrome Permutation (Easy)
214+
Given a string, determine if a permutation of the string could form a palindrome.
215+
216+
For example,
217+
"code" -> False, "aab" -> True, "carerac" -> True.
218+
219+
#### Solution
220+
1. Two pass的方法,第一遍扫描这个str, 统计每个字符的词频,然后第二遍判断是否出现了>1的奇数词频的char
221+
2. One pass 用set,char不在set里面,把char加进来,char在set里面,把char移除,最后判断set.size() == 0 || set.size() == 1 <br>
222+
这题和409相似
223+
224+
## 409. Longest Palindrome (Easy)
225+
Given a string which consists of lowercase or uppercase letters, find the length of the longest palindromes that can be built with those letters.
226+
227+
This is case sensitive, for example "Aa" is not considered a palindrome here.
228+
229+
Note:
230+
Assume the length of given string will not exceed 1,010.
231+
232+
Example:
233+
~~~
234+
Input:
235+
"abccccdd"
236+
237+
Output:
238+
7
239+
240+
Explanation:
241+
One longest palindrome that can be built is "dccaccd", whose length is 7.
242+
~~~~
243+
244+
#### Solution
245+
1. 笨方法也是扫描两边,第一遍统计每个单词出现的频率,第二遍数数
246+
2. One pass, 类似于266,用HashSet, char不在set里面,把char加进来,char在set里面,说明当前的char出现第二次了,count += 2, 最后如果set不为空的话,说明至少有一个char落单了,count += 1

Diff for: String/README.md

-85
Original file line numberDiff line numberDiff line change
@@ -1,85 +0,0 @@
1-
The Java code summarizes solutions for leetcode string problems.
2-
3-
# StringSolution.java
4-
5-
## 139. Word Break
6-
Given a non-empty string s and a dictionary wordDict containing a list of non-empty words, determine if s can be segmented into a space-separated sequence of one or more dictionary words. You may assume the dictionary does not contain duplicate words.
7-
8-
For example, given
9-
s = "leetcode",
10-
dict = ["leet", "code"].
11-
12-
Return true because "leetcode" can be segmented as "leet code".
13-
14-
#### Solution
15-
Dynamic Programming.
16-
1. One dimension array dp[], dp[i] means whether a substring from 0 to i (exclusive) has a valid word break or not.
17-
2. Transition formula: dp[i] = (dp[0] && dict.contains(s.substring(0, i + 1))) || (dp[1] && dict.contains(s.substring(1, i + 1)))) || ... || (dp[i] && dict.contains(s.substring(i, i + 1)))).
18-
19-
## 140. Word Break II
20-
Given a non-empty string s and a dictionary wordDict containing a list of non-empty words, add spaces in s to construct a sentence where each word is a valid dictionary word. You may assume the dictionary does not contain duplicate words.
21-
22-
Return all such possible sentences.
23-
24-
For example, given
25-
s = "catsanddog",
26-
dict = ["cat", "cats", "and", "sand", "dog"].
27-
28-
A solution is ["cats and dog", "cat sand dog"].
29-
30-
#### Solution
31-
Niiave backtacking got TLE with the test case:
32-
~~~~
33-
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
34-
["a","aa","aaa","aaaa","aaaaa","aaaaaa","aaaaaaa","aaaaaaaa","aaaaaaaaa","aaaaaaaaaa"]
35-
36-
answer: []
37-
~~~~
38-
39-
Use a HashMap<String, LinkedList<String>> map to store word breaks of substrings, so as to avoid duplicated search.
40-
41-
## 293. Flip Game (Easy)
42-
You are playing the following Flip Game with your friend: Given a string that contains only these two characters: + and -, you and your friend take turns to flip two consecutive "++" into "--". The game ends when a person can no longer make a move and therefore the other person will be the winner.
43-
44-
Write a function to compute all possible states of the string after one valid move.
45-
46-
For example, given s = "++++", after one move, it may become one of the following states:
47-
~~~~
48-
[
49-
"--++",
50-
"+--+",
51-
"++--"
52-
]
53-
~~~~
54-
If there is no valid move, return an empty list [].
55-
56-
#### Solution
57-
Simply iterate the string.
58-
59-
## 165. Compare Version Numbers
60-
Compare two version numbers version1 and version2.
61-
If version1 > version2 return 1, if version1 < version2 return -1, otherwise return 0.
62-
63-
You may assume that the version strings are non-empty and contain only digits and the . character.
64-
The . character does not represent a decimal point and is used to separate number sequences.
65-
For instance, 2.5 is not "two and a half" or "half way to version three", it is the fifth second-level revision of the second first-level revision.
66-
67-
Here is an example of version numbers ordering:
68-
~~~~
69-
0.1 < 1.1 < 1.2 < 13.37
70-
~~~~
71-
72-
#### Solution
73-
WRONG: my first idea is to compare v1 and v2 at their min length; and then handle the one that is longer. However, it becomes trivial to handle corner case, like "1.0" v.s. "1", and "01" v.s. "1".
74-
75-
~~~~
76-
for (int i = 0; i < Math.min(tokens1.length, tokens2.length); i++) {
77-
int v1 = Integer.parseInt(tokens1[i]);
78-
int v2 = Integer.parseInt(tokens2[i]);
79-
if (v1 != v2) {
80-
return v1 > v2 ? 1 : -1;
81-
}
82-
}
83-
~~~~
84-
85-
Think from the other side, compare at their max length, for the one which is shorter, simply set it to 0.

0 commit comments

Comments
 (0)