5. 最长回文子串
class Solution {
public String longestPalindrome(String s) {
String res = "";
for (int i = 0; i < s.length(); i++) {
// 以 s[i] 为中心的最长回文子串
String s1 = palindrome(s, i, i);
// 以 s[i] 和 s[i+1] 为中心的最长回文子串
String s2 = palindrome(s, i, i + 1);
// res = longest(res, s1, s2)
res = res.length() > s1.length() ? res : s1;
res = res.length() > s2.length() ? res : s2;
}
return res;
}
private String palindrome(String s,int left,int right){
while(left>=0 && right<s.length() && s.charAt(left)==s.charAt(right)){
left--;
right++;
}
//跳出 while 循环时,恰好满足 s.charAt(i) != s.charAt(j),因此不能取 left,不能取right
return s.substring(left+1,right);
}
}
public class Solution {
public String longestPalindrome(String s) {
// 特判
int len = s.length();
if (len < 2) {
return s;
}
int maxLen = 1;
int begin = 0;
// dp[i][j] 表示 s[i, j] 是否是回文串
boolean[][] dp = new boolean[len][len];
char[] charArray = s.toCharArray();
for (int i = 0; i < len; i++) {
dp[i][i] = true;
}
for (int j = 1; j < len; j++) {
for (int i = 0; i < j; i++) {
if (charArray[i] != charArray[j]) {
dp[i][j] = false;
} else {
if (j - i < 3) {
dp[i][j] = true;
} else {
dp[i][j] = dp[i + 1][j - 1];
}
}
// 只要 dp[i][j] == true 成立,就表示子串 s[i..j] 是回文,此时记录回文长度和起始位置
if (dp[i][j] && j - i + 1 > maxLen) {
maxLen = j - i + 1;
begin = i;
}
}
}
return s.substring(begin, begin + maxLen);
}
}
//可以称之为本题最强代码 大佬写得,借鉴学习了
class Solution {
public String longestPalindrome(String s) {
if (s == null || s.length() == 0) {
return "";
}
// 保存起始位置,测试了用数组似乎能比全局变量稍快一点
int[] range = new int[2];
char[] str = s.toCharArray();
for (int i = 0; i < s.length(); i++) {
// 把回文看成中间的部分全是同一字符,左右部分相对称
// 找到下一个与当前字符不同的字符
i = findLongest(str, i, range);
}
return s.substring(range[0], range[1] + 1);
}
public static int findLongest(char[] str, int low, int[] range) {
// 查找中间部分
int high = low;
while (high < str.length - 1 && str[high + 1] == str[low]) {
high++;
}
// 定位中间部分的最后一个字符
int ans = high;
// 从中间向左右扩散
while (low > 0 && high < str.length - 1 && str[low - 1] == str[high + 1]) {
low--;
high++;
}
// 记录最大长度
if (high - low > range[1] - range[0]) {
range[0] = low;
range[1] = high;
}
return ans;
}
}
面试题 01.02. 判定是否互为字符重排
// 代码不正确!!! 比如 ac 和 bb
class Solution {
public boolean CheckPermutation(String s1, String s2) {
int count = 0;
if(s1.length()!=s2.length()){
return false;
}
for(int i = 0;i<s1.length();i++){
count += s1.charAt(i);
count -= s2.charAt(i);
}
return count==0?true:false;
}
}
class Solution {
public boolean CheckPermutation(String s1, String s2) {
int count = 0;
if(s1.length() != s2.length()){
return false;
}
int[] arr = new int[128];
for(int i = 0; i < s1.length();i++){
arr[s1.charAt(i)-'A']++;
arr[s2.charAt(i)-'A']--;
}
for(int i = 0;i < 128;i++){
if(arr[i]!=0){
return false;
}
}
return true;
}
}
class Solution {
public boolean CheckPermutation(String s1, String s2) {
if (s1 == s2)
return true;
if (s1 == null || s2 == null || s1.length() != s2.length())
return false;
final char[] c1 = s1.toCharArray();
final char[] c2 = s2.toCharArray();
Arrays.sort(c1);
Arrays.sort(c2);
return Arrays.equals(c1, c2);
}
}
面试题 16.10. 生存人数
class Solution {
public int maxAliveYear(int[] birth, int[] death) {
/*
类似 1109、航班预订统计,我们将某个点出生的人加起来,将某个点死去的人减去
*/
int len = birth.length;
int[] people = new int[102];
for(int i = 0; i < len; i++){
people[birth[i] - 1900]++;
people[death[i] - 1899]--;
}
int maxYear = 0;
for(int i = 1; i <= 100; i++){
people[i] += people[i - 1];
if(people[maxYear] < people[i]){
maxYear = i;
}
}
return maxYear + 1900;
}
}
你知道的越多,你不知道的越多。