【牛客刷题】最长无重复子数组、最长公共子串、最长回文子串

  最长无重复子数组_牛客题霸_牛客网

 双指针:

从数组的第一个元素开始向后遍历的。两个指针`start`和`end`都是从数组的开始处出发。`end`指针会逐个遍历整个数组,而`start`指针只会在需要跳过重复元素时移动。

例如,对于数组 `[1,2,3,4,1,5,6,7,8,1]`,开始时`start=0`,`end=0`。当`end`遍历到第二个`1`时(即`arr[4]`),`start`指针会跳过第一个`1`,移动到`arr[1]`(即元素`2`)处。

这样,`[start, end]`区间内的子数组就没有重复元素,我们只需要记录这个区间的长度,并与目前找到的最大长度比较即可。

`lastPos`这个`unordered_map`是用来快速查找一个元素最后出现的位置,以便我们能够迅速更新`start`指针。

int maxLength(vector<int>& arr) {
        if (arr.empty()) return 0;

        int maxLen = 0;
        unordered_map<int, int> lastPos;
        int start = 0;

        for (int end = 0; end < arr.size(); ++end) {
            // 更新start指针位置
            if (lastPos.find(arr[end]) != lastPos.end() && lastPos[arr[end]] >= start) {
                start = lastPos[arr[end]] + 1;
            }

            // 更新元素最后出现的位置
            lastPos[arr[end]] = end;

            // 更新最大长度
            maxLen = max(maxLen, end - start + 1);
        }

        return maxLen;
    }

最长公共子串_牛客题霸_牛客网

 记录下标就好,然后用substr函数,str1.substr(maxIndex - maxLen, maxLen);

`substr` 是一个常用于C++ `std::string` 类中的成员函数,用于从一个字符串中提取一个子串。这个函数有两个参数:

1. `pos`(起始位置):从哪个位置开始提取子串。位置从 0 开始计数。
2. `len`(长度):要提取的子串的长度。

    string LCS(string str1, string str2) {
        // write code here
        int maxLen = 0;
        int maxIndex;
        vector<vector<int>> dp(str1.size() + 1, vector<int> (str2.size() + 1, 0));
        for (int i = 1; i <= str1.size(); i++) {
            for (int j = 1; j <= str2.size(); j++) {
                if (str1[i-1] == str2[j-1]) {
                    dp[i][j] = dp[i-1][j-1] + 1; 
                }
                
                if (maxLen < dp[i][j]) {
                        maxIndex = i;
                        maxLen = dp[i][j];
                }
            }
        }
        string res = str1.substr(maxIndex - maxLen, maxLen);

        return res;
    }

最长回文子串_牛客题霸_牛客网

注意和 最长回文子序列 不一样,类似于求 回文子串总数,用bool类型的dp,记得在当dp[i][j]=true时更新maxLen=max(maxLen, j - i +1),此外i从size()-1开始,j 从 i 开始。 


    int getLongestPalindrome(string A) {
        // write code here
        vector<vector<bool>> dp(A.size(), vector<bool>(A.size(), false));
        int maxLen = 1;
        for (int i = A.size() - 1; i >= 0; i--) {
            for (int j = i; j < A.size(); j++) {
                if (A[i] == A[j]) {
                    if ((j - i) <= 1) {
                        dp[i][j] = true;
                    } else if (dp[i + 1][j - 1] == true) {
                        if (A[i] == A[j]) {
                            dp[i][j] = true;
                        }
                    }
                    if (dp[i][j]) maxLen = max(maxLen, j - i + 1);
                }
            }
        }
        return maxLen;
    }

猜你喜欢

转载自blog.csdn.net/weixin_43785314/article/details/132677357