面试中经典高频算法分享(转自力扣)

1、无重复字符的最长子串

给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。

力扣:力扣

解:以这个字符串为例:abcabcbb,当i等于3时,也就是指向了第二个a, 此时我就需要查之前有没有出现过a, 如果出现了是在哪一个位置出现的。然后通过last[index] 查到等于1, 也就是说,如果start 依然等于0的话,那么当前窗口就有两个a了,也就是字符串重复了,所以我们需要移动当前窗口的start指针,移动到什么地方呢?移动到什么地方,窗口内就没有重复元素了呢? 对了,就是a上一次出现的位置的下一个位置,就是1 + 1 = 2。当start == 2, 当前窗口就没有了重复元素,那么以当前字符为结尾的最长无重复子串就是bca,然后再和之前的res取最大值。然后i指向后面的位置,按照同样思路计算。

public static int lengthOfLongestSubstring(String s) {
        // 记录字符上一次出现的位置
        int[] last = new int[128];

        int n = s.length();

        int res = 0;
        int start = 0; // 窗口开始位置
        for(int i = 0; i < n; i++) {
            int index = s.charAt(i);
            start = Math.max(start, last[index]);
            res   = Math.max(res, i - start + 1);
            last[index] = i+1;
        }

        return res;
    }

2、两整数之和

力扣:力扣

面试中经典高频算法分享(转自力扣)_第1张图片

class Solution {
    public int getSum(int a, int b) {
        while (b != 0) {
            int carry = (a & b) << 1;
            a = a ^ b;
            b = carry;
        }
        return a;
    }
}

3、贪心算法:

3.1超级洗衣机:

力扣:力扣

面试中经典高频算法分享(转自力扣)_第2张图片

面试中经典高频算法分享(转自力扣)_第3张图片

面试中经典高频算法分享(转自力扣)_第4张图片

class Solution {
    public int findMinMoves(int[] machines) {
        int count = Arrays.stream(machines).sum();
        if (count % machines.length != 0) {
            return -1;
        }
        int result = 0, sum = 0;
        int avg = count / machines.length;
        for (int machine : machines) {
            machine = machine -avg;
            sum = sum + machine;
            result = Math.max(result, Math.max(Math.abs(sum), machine));
        }
        return result;
    }
}

4、动态规划:

4.1、最长回文子串:

力扣:力扣

解题思路:

解法1:动态规划

面试中经典高频算法分享(转自力扣)_第5张图片

面试中经典高频算法分享(转自力扣)_第6张图片

class Solution {
    public String longestPalindrome(String s) {
        int len = s.length();
        if (len < 2){
            return s;
        }
        // dp[i][j] 表示 s[i..j] 是否是回文串
        boolean[][] dp = new boolean[len][len];
        //初始化 长度为1的 是回文字符
        for (int i = 0; i < len; i++) {
            dp[i][i] = true;
        }
        int begin = 0;
        int maxLen = 1;
        char[] chars = s.toCharArray();
        // 递推开始
        // 先枚举子串长度
        for (int j = 1; j < len; j++) {
            for (int i = 0; i < j; i++) {
                if (chars[i] != chars[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][L] == true 成立,就表示子串 s[i..L] 是回文,此时记录回文长度和起始位置
                if (dp[i][j] && j-i + 1 > maxLen){
                    begin = i;
                    maxLen = j-i + 1;
                }
            }
        }
        return s.substring(begin, maxLen + begin);
    }
}

解法2:中心扩散 

面试中经典高频算法分享(转自力扣)_第7张图片

public String longestPalindrome(String s) {
        int len = s.length();
        if (len < 2) {
            return s;
        }
        int begin = 0, maxLen = 1;
        for (int i = 0; i < len - 1; i++) {
            int res1 = expandAroundCenter(s, i, i); //奇数
            int res2 = expandAroundCenter(s, i, i + 1); //偶数
            int curMaxLen = Math.max(res1, res2);
            if (curMaxLen > maxLen) {
                maxLen = curMaxLen;
                // i为中心长度为 maxLen 的字符串起始位置计算方式
                begin = i - (maxLen - 1) / 2;
            }
        }
        return s.substring(begin, begin + maxLen);
    }

    private int expandAroundCenter(String s, int i, int j) {
        while (i >= 0 && j < s.length() && s.charAt(i) == s.charAt(j)) {
            i--;
            j++;
        }
        //跳出循环的时候 满足: s.charAt(i) != s.charAt(j)
        // 所以长度为 j - i + 1 - 2 = j - i - 1;
        return j - i - 1;
    }

5、最长公共子序列:

力扣:力扣

面试中经典高频算法分享(转自力扣)_第8张图片

面试中经典高频算法分享(转自力扣)_第9张图片

面试中经典高频算法分享(转自力扣)_第10张图片

class Solution {
    public int longestCommonSubsequence(String text1, String text2) {
        int m = text1.length(), n = text2.length();
        int[][] dp = new int[m + 1][n + 1];
        for (int i = 1; i <= m; i++) {
            char c1 = text1.charAt(i - 1);
            for (int j = 1; j <= n; j++) {
                char c2 = text2.charAt(j - 1);
                if (c1 == c2) {
                    dp[i][j] = dp[i - 1][j - 1] + 1;
                } else {
                    dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
                }
            }
        }
        return dp[m][n];
    }
}

你可能感兴趣的:(Java基础,算法,leetcode,动态规划)