力扣---2020.5.21

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;
    }
}

你知道的越多,你不知道的越多。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值