Skip to content

Commit a079c49

Browse files
author
王鹏
committed
feat(MEDIUM): add _647_countSubstrings
1 parent 3e60c81 commit a079c49

File tree

1 file changed

+138
-0
lines changed

1 file changed

+138
-0
lines changed
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
package pp.arithmetic.leetcode;
2+
3+
import java.util.Stack;
4+
5+
/**
6+
* Created by wangpeng on 2019-09-26.
7+
* 647. 回文子串
8+
* <p>
9+
* 给定一个字符串,你的任务是计算这个字符串中有多少个回文子串。
10+
* <p>
11+
* 具有不同开始位置或结束位置的子串,即使是由相同的字符组成,也会被计为是不同的子串。
12+
* <p>
13+
* 示例 1:
14+
* <p>
15+
* 输入: "abc"
16+
* 输出: 3
17+
* 解释: 三个回文子串: "a", "b", "c".
18+
* 示例 2:
19+
* <p>
20+
* 输入: "aaa"
21+
* 输出: 6
22+
* 说明: 6个回文子串: "a", "a", "a", "aa", "aa", "aaa".
23+
* 注意:
24+
* <p>
25+
* 输入的字符串长度不会超过1000。
26+
* <p>
27+
* 来源:力扣(LeetCode)
28+
* 链接:https://leetcode-cn.com/problems/palindromic-substrings
29+
* 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
30+
*/
31+
public class _647_countSubstrings {
32+
public static void main(String[] args) {
33+
_647_countSubstrings countSubstrings = new _647_countSubstrings();
34+
//1
35+
System.out.println(countSubstrings.countSubstrings("abc"));
36+
System.out.println(countSubstrings.countSubstrings("aaa"));
37+
System.out.println(countSubstrings.countSubstrings("abab"));
38+
//2
39+
System.out.println(countSubstrings.countSubstrings2("abc"));
40+
System.out.println(countSubstrings.countSubstrings2("aaa"));
41+
System.out.println(countSubstrings.countSubstrings2("abab"));
42+
//3
43+
System.out.println(countSubstrings.countSubstrings3("abc"));
44+
System.out.println(countSubstrings.countSubstrings3("aaa"));
45+
System.out.println(countSubstrings.countSubstrings3("abab"));
46+
47+
}
48+
49+
/**
50+
* 解法一:
51+
* 定义两个指针,从0到len判断所有的回文可能性,性能不一定高,结果一定对(时间复杂度O(n^3))
52+
* 执行用时 :116 ms, 在所有 Java 提交中击败了12.26%的用户
53+
* 内存消耗 :34.3 MB, 在所有 Java 提交中击败了92.34%的用户
54+
* <p>
55+
* 解法二:{@link _647_countSubstrings#countSubstrings2(String)}
56+
*
57+
* @param s
58+
* @return
59+
*/
60+
public int countSubstrings(String s) {
61+
int retCount = 0;
62+
int start, end;
63+
for (start = 0; start < s.length(); start++) {
64+
for (end = start; end < s.length(); end++) {
65+
if (isPalindrome(s, start, end)) {
66+
retCount++;
67+
}
68+
}
69+
}
70+
71+
return retCount;
72+
}
73+
74+
private boolean isPalindrome(String s, int start, int end) {
75+
while (start <= end) {
76+
if (s.charAt(start) != s.charAt(end)) {
77+
return false;
78+
}
79+
start++;
80+
end--;
81+
}
82+
return true;
83+
}
84+
85+
/**
86+
* 解法二:中心扩展==>时间复杂度O(n^2)
87+
* 从中心(区分1个点的中心还是两个点的中心)向两边同时扩散,如左右两边都相等则是回文,继续扩散
88+
*
89+
* 执行用时 :2 ms , 在所有 Java 提交中击败了99.02%的用户
90+
* 内存消耗 :34 MB, 在所有 Java 提交中击败了92.79%的用户
91+
*
92+
* @param s
93+
* @return
94+
*/
95+
public int countSubstrings2(String s) {
96+
int res = 0;
97+
for (int i = 0; i < s.length(); i++) {
98+
//分奇偶考虑
99+
res += countSegment(s, i, i);
100+
res += countSegment(s, i, i + 1);
101+
}
102+
return res;
103+
}
104+
105+
//start往左边跑,end往右边跑, 判断s[start, end]是否为回文
106+
public int countSegment(String s, int start, int end) {
107+
int count = 0;
108+
while (start >= 0 && end < s.length() && s.charAt(start--) == s.charAt(end++))
109+
count++;
110+
return count;
111+
}
112+
113+
/**
114+
* 解法三:动态规划==>时间复杂度O(n^2)
115+
* 基本原理同解法二,只是用动态规划的方式求解出来了
116+
*
117+
* 执行用时 :11 ms, 在所有 Java 提交中击败了47.66%的用户
118+
* 内存消耗 :35.6 MB, 在所有 Java 提交中击败了86.94%的用户
119+
* @param s
120+
* @return
121+
*/
122+
public static int countSubstrings3(String s) {
123+
int result = 0;
124+
boolean[][] dp = new boolean[s.length()][s.length()];
125+
126+
for (int i = s.length()-1; i >=0 ; i--) {
127+
for (int j = i; j < s.length(); j++) {
128+
if (i==j)
129+
dp[i][j] = true;
130+
else
131+
dp[i][j] = s.charAt(i)==s.charAt(j) && (j<=i+1 || dp[i+1][j-1]);
132+
if (dp[i][j]) result++;
133+
}
134+
}
135+
136+
return result;
137+
}
138+
}

0 commit comments

Comments
 (0)